aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-06-17 14:53:45 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-06-17 14:53:45 +0100
commit63bbec8a63590d7f743a0b365f77fd4d25aa8a50 (patch)
tree6bffedfe90ea249acea3ba01ee20936cd03c7e8a
parent1ed6717ae5faa705c295101b7d5a19f9d71652e2 (diff)
parent059f8d8526915f5c70c54edb3d7e5df7cd2970c7 (diff)
downloadpaludis-63bbec8a63590d7f743a0b365f77fd4d25aa8a50.tar.gz
paludis-63bbec8a63590d7f743a0b365f77fd4d25aa8a50.tar.xz
Merge branch 'new-orderer'
-rw-r--r--.gitignore1
-rw-r--r--paludis/resolver/Makefile.am65
-rw-r--r--paludis/resolver/decider.cc290
-rw-r--r--paludis/resolver/decider.hh57
-rw-r--r--paludis/resolver/decision.cc84
-rw-r--r--paludis/resolver/decision.hh12
-rw-r--r--paludis/resolver/decisions-fwd.hh (renamed from paludis/resolver/failure_kinds-fwd.hh)20
-rw-r--r--paludis/resolver/decisions.cc211
-rw-r--r--paludis/resolver/decisions.hh104
-rw-r--r--paludis/resolver/failure_kinds.se14
-rw-r--r--paludis/resolver/job-fwd.hh16
-rw-r--r--paludis/resolver/job.cc804
-rw-r--r--paludis/resolver/job.hh287
-rw-r--r--paludis/resolver/job_id.cc67
-rw-r--r--paludis/resolver/job_list-fwd.hh (renamed from paludis/resolver/resolutions-fwd.hh)14
-rw-r--r--paludis/resolver/job_list.cc124
-rw-r--r--paludis/resolver/job_list.hh76
-rw-r--r--paludis/resolver/job_lists-fwd.hh (renamed from paludis/resolver/jobs-fwd.hh)8
-rw-r--r--paludis/resolver/job_lists.cc48
-rw-r--r--paludis/resolver/job_lists.hh (renamed from paludis/resolver/arrow.hh)32
-rw-r--r--paludis/resolver/job_requirements-fwd.hh (renamed from paludis/resolver/job_id-fwd.hh)15
-rw-r--r--paludis/resolver/job_requirements.cc (renamed from paludis/resolver/arrow.cc)45
-rw-r--r--paludis/resolver/job_requirements.hh57
-rw-r--r--paludis/resolver/job_requirements.se16
-rw-r--r--paludis/resolver/job_state-fwd.hh2
-rw-r--r--paludis/resolver/job_state.cc150
-rw-r--r--paludis/resolver/job_state.hh70
-rw-r--r--paludis/resolver/jobs.cc299
-rw-r--r--paludis/resolver/jobs.hh75
-rw-r--r--paludis/resolver/nag-fwd.hh (renamed from paludis/resolver/failure_kinds.hh)11
-rw-r--r--paludis/resolver/nag.cc370
-rw-r--r--paludis/resolver/nag.hh94
-rw-r--r--paludis/resolver/orderer-fwd.hh6
-rw-r--r--paludis/resolver/orderer.cc965
-rw-r--r--paludis/resolver/orderer.hh50
-rw-r--r--paludis/resolver/orderer_notes-fwd.hh (renamed from paludis/resolver/resolver_lists-fwd.hh)8
-rw-r--r--paludis/resolver/orderer_notes.cc (renamed from paludis/resolver/failure_kinds.cc)29
-rw-r--r--paludis/resolver/orderer_notes.hh (renamed from paludis/resolver/job_id.hh)23
-rw-r--r--paludis/resolver/resolution.cc1
-rw-r--r--paludis/resolver/resolutions.cc101
-rw-r--r--paludis/resolver/resolutions_by_resolvent-fwd.hh31
-rw-r--r--paludis/resolver/resolutions_by_resolvent.cc119
-rw-r--r--paludis/resolver/resolutions_by_resolvent.hh (renamed from paludis/resolver/resolutions.hh)33
-rw-r--r--paludis/resolver/resolved-fwd.hh33
-rw-r--r--paludis/resolver/resolved.cc71
-rw-r--r--paludis/resolver/resolved.hh66
-rw-r--r--paludis/resolver/resolvent.hh7
-rw-r--r--paludis/resolver/resolver.cc43
-rw-r--r--paludis/resolver/resolver.hh6
-rw-r--r--paludis/resolver/resolver_TEST_any.cc188
-rw-r--r--paludis/resolver/resolver_TEST_blockers.cc233
-rwxr-xr-xpaludis/resolver/resolver_TEST_blockers_setup.sh55
-rw-r--r--paludis/resolver/resolver_TEST_continue_on_failure.cc159
-rwxr-xr-xpaludis/resolver/resolver_TEST_continue_on_failure_cleanup.sh9
-rwxr-xr-xpaludis/resolver/resolver_TEST_continue_on_failure_setup.sh56
-rw-r--r--paludis/resolver/resolver_TEST_cycles.cc183
-rwxr-xr-xpaludis/resolver/resolver_TEST_cycles_setup.sh35
-rw-r--r--paludis/resolver/resolver_TEST_errors.cc42
-rw-r--r--paludis/resolver/resolver_TEST_serialisation.cc56
-rw-r--r--paludis/resolver/resolver_TEST_simple.cc132
-rwxr-xr-xpaludis/resolver/resolver_TEST_simple_setup.sh70
-rw-r--r--paludis/resolver/resolver_TEST_suggestions.cc143
-rwxr-xr-xpaludis/resolver/resolver_TEST_suggestions_setup.sh2
-rw-r--r--paludis/resolver/resolver_TEST_virtuals.cc91
-rw-r--r--paludis/resolver/resolver_functions.hh6
-rw-r--r--paludis/resolver/resolver_lists.cc96
-rw-r--r--paludis/resolver/resolver_lists.hh62
-rw-r--r--paludis/resolver/resolver_test.cc349
-rw-r--r--paludis/resolver/resolver_test.hh64
-rw-r--r--paludis/resolver/sanitised_dependencies.cc40
-rw-r--r--paludis/resolver/sanitised_dependencies.hh6
-rw-r--r--paludis/resolver/strongly_connected_component-fwd.hh (renamed from paludis/resolver/arrow-fwd.hh)12
-rw-r--r--paludis/resolver/strongly_connected_component.cc36
-rw-r--r--paludis/resolver/strongly_connected_component.hh59
-rw-r--r--src/clients/cave/Makefile.am6
-rw-r--r--src/clients/cave/cmd_display_resolution.cc467
-rw-r--r--src/clients/cave/cmd_display_resolution.hh4
-rw-r--r--src/clients/cave/cmd_execute_resolution.cc882
-rw-r--r--src/clients/cave/cmd_execute_resolution.hh4
-rw-r--r--src/clients/cave/cmd_resolve_dump.cc23
-rwxr-xr-xsrc/clients/cave/continue_on_failure_TEST56
-rwxr-xr-xsrc/clients/cave/continue_on_failure_TEST_cleanup.sh9
-rwxr-xr-xsrc/clients/cave/continue_on_failure_TEST_setup.sh257
-rw-r--r--src/clients/cave/resolve_common.cc64
84 files changed, 4610 insertions, 4476 deletions
diff --git a/.gitignore b/.gitignore
index 8d63900..db321be 100644
--- a/.gitignore
+++ b/.gitignore
@@ -326,6 +326,7 @@ paludis-*.*.*.tar.bz2
/paludis/repository_name_cache_TEST
/paludis/resolver/resolver_TEST_any
/paludis/resolver/resolver_TEST_blockers
+/paludis/resolver/resolver_TEST_continue_on_failure
/paludis/resolver/resolver_TEST_cycles
/paludis/resolver/resolver_TEST_errors
/paludis/resolver/resolver_TEST_serialisation
diff --git a/paludis/resolver/Makefile.am b/paludis/resolver/Makefile.am
index d488be0..7ef1706 100644
--- a/paludis/resolver/Makefile.am
+++ b/paludis/resolver/Makefile.am
@@ -3,8 +3,8 @@ include $(top_srcdir)/misc/common-makefile.am
DISTCLEANFILES = \
any_child_score-se.hh any_child_score-se.cc \
change_type-se.hh change_type-se.cc \
+ job_requirements-se.hh job_requirements-se.cc \
destination_types-se.hh destination_types-se.cc \
- failure_kinds-se.hh failure_kinds-se.cc \
resolver_functions-se.hh resolver_functions-se.cc \
use_existing-se.hh use_existing-se.cc
AM_CXXFLAGS = -I$(top_srcdir) @PALUDIS_CXXFLAGS@ @PALUDIS_CXXFLAGS_VISIBILITY@
@@ -12,7 +12,7 @@ EXTRA_DIST = \
any_child_score-se.hh any_child_score-se.cc any_child_score.se \
change_type-se.hh change_type-se.cc change_type.se \
destination_types-se.hh destination_types-se.cc destination_types.se \
- failure_kinds-se.hh failure_kinds-se.cc failure_kinds.se \
+ job_requirements-se.hh job_requirements-se.cc job_requirements.se \
resolver_functions-se.hh resolver_functions-se.cc resolver_functions.se \
use_existing-se.hh use_existing-se.cc use_existing.se \
$(check_SCRIPTS)
@@ -20,68 +20,74 @@ BUILT_SOURCES = \
any_child_score-se.hh any_child_score-se.cc \
change_type-se.hh change_type-se.cc \
destination_types-se.hh destination_types-se.cc \
- failure_kinds-se.hh failure_kinds-se.cc \
+ job_requirements-se.hh job_requirements-se.cc \
resolver_functions-se.hh resolver_functions-se.cc \
use_existing-se.hh use_existing-se.cc
noinst_HEADERS = \
any_child_score.hh any_child_score-fwd.hh any_child_score-se.hh \
- arrow.hh arrow-fwd.hh \
change_type.hh change_type-fwd.hh change_type-se.hh \
constraint.hh constraint-fwd.hh \
decider.hh decider-fwd.hh \
decision.hh decision-fwd.hh \
+ decisions.hh decisions-fwd.hh \
destination.hh destination-fwd.hh \
destination_types.hh destination_types-fwd.hh destination_types-se.hh \
- failure_kinds.hh failure_kinds-fwd.hh failure_kinds-se.hh \
job.hh job-fwd.hh \
- job_id.hh job_id-fwd.hh \
+ job_list.hh job_list-fwd.hh \
+ job_lists.hh job_lists-fwd.hh \
+ job_requirements.hh job_requirements-fwd.hh \
job_state.hh job_state-fwd.hh \
- jobs.hh jobs-fwd.hh \
+ nag.hh nag-fwd.hh \
orderer.hh orderer-fwd.hh \
+ orderer_notes.hh orderer_notes-fwd.hh \
package_or_block_dep_spec.hh package_or_block_dep_spec-fwd.hh \
reason.hh reason-fwd.hh \
required_confirmations.hh required_confirmations-fwd.hh \
resolution.hh resolution-fwd.hh \
- resolutions.hh resolutions-fwd.hh \
+ resolutions_by_resolvent.hh resolutions_by_resolvent-fwd.hh \
+ resolved.hh resolved-fwd.hh \
resolvent.hh resolvent-fwd.hh \
resolver.hh resolver-fwd.hh \
resolver_functions.hh resolver_functions-fwd.hh \
- resolver_lists.hh resolver_lists-fwd.hh \
sanitised_dependencies.hh sanitised_dependencies-fwd.hh \
slot_name_or_null.hh slot_name_or_null-fwd.hh \
spec_rewriter.hh spec_rewriter-fwd.hh \
+ strongly_connected_component.hh strongly_connected_component-fwd.hh \
suggest_restart.hh suggest_restart-fwd.hh \
unsuitable_candidates.hh unsuitable_candidates-fwd.hh \
use_existing.hh use_existing-fwd.hh use_existing-se.hh
libpaludisresolver_a_SOURCES = \
any_child_score.cc \
- arrow.cc \
change_type.cc \
constraint.cc \
decider.cc \
decision.cc \
+ decisions.cc \
destination.cc \
destination_types.cc \
- failure_kinds.cc \
job.cc \
- job_id.cc \
+ job_list.cc \
+ job_lists.cc \
+ job_requirements.cc \
job_state.cc \
- jobs.cc \
+ nag.cc \
orderer.cc \
+ orderer_notes.cc \
package_or_block_dep_spec.cc \
reason.cc \
required_confirmations.cc \
resolution.cc \
- resolutions.cc \
+ resolutions_by_resolvent.cc \
+ resolved.cc \
resolvent.cc \
resolver.cc \
resolver_functions.cc \
- resolver_lists.cc \
sanitised_dependencies.cc \
slot_name_or_null.cc \
spec_rewriter.cc \
+ strongly_connected_component.cc \
suggest_restart.cc \
unsuitable_candidates.cc \
use_existing.cc
@@ -101,6 +107,7 @@ TESTS = \
resolver_TEST_suggestions \
resolver_TEST_any \
resolver_TEST_errors \
+ resolver_TEST_continue_on_failure \
$(virtuals_tests)
endif
@@ -114,7 +121,8 @@ check_SCRIPTS = \
resolver_TEST_simple_setup.sh resolver_TEST_simple_cleanup.sh \
resolver_TEST_virtuals_setup.sh resolver_TEST_virtuals_cleanup.sh \
resolver_TEST_any_setup.sh resolver_TEST_any_cleanup.sh \
- resolver_TEST_errors_setup.sh resolver_TEST_errors_cleanup.sh
+ resolver_TEST_errors_setup.sh resolver_TEST_errors_cleanup.sh \
+ resolver_TEST_continue_on_failure_setup.sh resolver_TEST_continue_on_failure_cleanup.sh
check_LIBRARIES = libpaludisresolvertest.a
libpaludisresolvertest_a_SOURCES = \
@@ -225,18 +233,25 @@ resolver_TEST_errors_LDADD = \
resolver_TEST_errors_CXXFLAGS = $(AM_CXXFLAGS) @PALUDIS_CXXFLAGS_NO_DEBUGGING@
+resolver_TEST_continue_on_failure_SOURCES = resolver_TEST_continue_on_failure.cc
+
+resolver_TEST_continue_on_failure_LDADD = \
+ libpaludisresolvertest.a \
+ $(top_builddir)/paludis/util/test_extras.o \
+ $(top_builddir)/test/libtest.a \
+ $(top_builddir)/paludis/libpaludis_@PALUDIS_PC_SLOT@.la \
+ $(top_builddir)/paludis/util/libpaludisutil_@PALUDIS_PC_SLOT@.la \
+ libpaludisresolver.a \
+ $(DYNAMIC_LD_LIBS)
+
+resolver_TEST_continue_on_failure_CXXFLAGS = $(AM_CXXFLAGS) @PALUDIS_CXXFLAGS_NO_DEBUGGING@
+
use_existing-se.hh : use_existing.se $(top_srcdir)/misc/make_se.bash
if ! $(top_srcdir)/misc/make_se.bash --header $(srcdir)/use_existing.se > $@ ; then rm -f $@ ; exit 1 ; fi
use_existing-se.cc : use_existing.se $(top_srcdir)/misc/make_se.bash
if ! $(top_srcdir)/misc/make_se.bash --source $(srcdir)/use_existing.se > $@ ; then rm -f $@ ; exit 1 ; fi
-failure_kinds-se.hh : failure_kinds.se $(top_srcdir)/misc/make_se.bash
- if ! $(top_srcdir)/misc/make_se.bash --header $(srcdir)/failure_kinds.se > $@ ; then rm -f $@ ; exit 1 ; fi
-
-failure_kinds-se.cc : failure_kinds.se $(top_srcdir)/misc/make_se.bash
- if ! $(top_srcdir)/misc/make_se.bash --source $(srcdir)/failure_kinds.se > $@ ; then rm -f $@ ; exit 1 ; fi
-
destination_types-se.hh : destination_types.se $(top_srcdir)/misc/make_se.bash
if ! $(top_srcdir)/misc/make_se.bash --header $(srcdir)/destination_types.se > $@ ; then rm -f $@ ; exit 1 ; fi
@@ -261,3 +276,9 @@ resolver_functions-se.hh : resolver_functions.se $(top_srcdir)/misc/make_se.bash
resolver_functions-se.cc : resolver_functions.se $(top_srcdir)/misc/make_se.bash
if ! $(top_srcdir)/misc/make_se.bash --source $(srcdir)/resolver_functions.se > $@ ; then rm -f $@ ; exit 1 ; fi
+job_requirements-se.hh : job_requirements.se $(top_srcdir)/misc/make_se.bash
+ if ! $(top_srcdir)/misc/make_se.bash --header $(srcdir)/job_requirements.se > $@ ; then rm -f $@ ; exit 1 ; fi
+
+job_requirements-se.cc : job_requirements.se $(top_srcdir)/misc/make_se.bash
+ if ! $(top_srcdir)/misc/make_se.bash --source $(srcdir)/job_requirements.se > $@ ; then rm -f $@ ; exit 1 ; fi
+
diff --git a/paludis/resolver/decider.cc b/paludis/resolver/decider.cc
index ce14810..8d00177 100644
--- a/paludis/resolver/decider.cc
+++ b/paludis/resolver/decider.cc
@@ -25,12 +25,12 @@
#include <paludis/resolver/constraint.hh>
#include <paludis/resolver/decision.hh>
#include <paludis/resolver/destination.hh>
-#include <paludis/resolver/resolutions.hh>
+#include <paludis/resolver/resolutions_by_resolvent.hh>
#include <paludis/resolver/suggest_restart.hh>
#include <paludis/resolver/reason.hh>
#include <paludis/resolver/unsuitable_candidates.hh>
#include <paludis/resolver/resolver.hh>
-#include <paludis/resolver/resolver_lists.hh>
+#include <paludis/resolver/required_confirmations.hh>
#include <paludis/util/exception.hh>
#include <paludis/util/stringify.hh>
#include <paludis/util/make_named_values.hh>
@@ -40,6 +40,7 @@
#include <paludis/util/enum_iterator.hh>
#include <paludis/util/indirect_iterator-impl.hh>
#include <paludis/util/tribool.hh>
+#include <paludis/util/simple_visitor_cast.hh>
#include <paludis/environment.hh>
#include <paludis/notifier_callback.hh>
#include <paludis/repository.hh>
@@ -65,8 +66,6 @@
using namespace paludis;
using namespace paludis::resolver;
-typedef std::map<Resolvent, std::tr1::shared_ptr<Resolution> > ResolutionsByResolventMap;
-
namespace paludis
{
template <>
@@ -76,23 +75,21 @@ namespace paludis
const ResolverFunctions fns;
SpecRewriter rewriter;
- ResolutionsByResolventMap resolutions_by_resolvent;
-
- const std::tr1::shared_ptr<ResolverLists> lists;
+ const std::tr1::shared_ptr<ResolutionsByResolvent> resolutions_by_resolvent;
Implementation(const Environment * const e, const ResolverFunctions & f,
- const std::tr1::shared_ptr<ResolverLists> & l) :
+ const std::tr1::shared_ptr<ResolutionsByResolvent> & l) :
env(e),
fns(f),
rewriter(env),
- lists(l)
+ resolutions_by_resolvent(l)
{
}
};
}
Decider::Decider(const Environment * const e, const ResolverFunctions & f,
- const std::tr1::shared_ptr<ResolverLists> & l) :
+ const std::tr1::shared_ptr<ResolutionsByResolvent> & l) :
PrivateImplementationPattern<Decider>(new Implementation<Decider>(e, f, l))
{
}
@@ -116,26 +113,26 @@ Decider::_resolve_decide_with_dependencies()
break;
changed = false;
- for (ResolutionsByResolventMap::iterator i(_imp->resolutions_by_resolvent.begin()),
- i_end(_imp->resolutions_by_resolvent.end()) ;
+ for (ResolutionsByResolvent::ConstIterator i(_imp->resolutions_by_resolvent->begin()),
+ i_end(_imp->resolutions_by_resolvent->end()) ;
i != i_end ; ++i)
{
/* we've already decided */
- if (i->second->decision())
+ if ((*i)->decision())
continue;
/* we're only being suggested. don't do this on the first pass, so
* we don't have to do restarts for suggestions later becoming hard
* deps. */
- if (state == deciding_non_suggestions && i->second->constraints()->all_untaken())
+ if (state == deciding_non_suggestions && (*i)->constraints()->all_untaken())
continue;
_imp->env->trigger_notifier_callback(NotifierCallbackResolverStepEvent());
changed = true;
- _decide(i->first, i->second);
+ _decide(*i);
- _add_dependencies_if_necessary(i->first, i->second);
+ _add_dependencies_if_necessary(*i);
}
}
}
@@ -173,15 +170,15 @@ Decider::_resolve_dependents()
Resolvent resolvent(*s, dt_install_to_slash);
/* we've changed things if we've not already done anything for this resolvent */
- if (_imp->resolutions_by_resolvent.end() == _imp->resolutions_by_resolvent.find(resolvent))
+ if (_imp->resolutions_by_resolvent->end() == _imp->resolutions_by_resolvent->find(resolvent))
changed = true;
const std::tr1::shared_ptr<Resolution> resolution(_resolution_for_resolvent(resolvent, true));
const std::tr1::shared_ptr<const ConstraintSequence> constraints(_make_constraints_for_dependent(
- resolvent, resolution, *s, dependent_upon));
+ resolution, *s, dependent_upon));
for (ConstraintSequence::ConstIterator c(constraints->begin()), c_end(constraints->end()) ;
c != c_end ; ++c)
- _apply_resolution_constraint(resolvent, resolution, *c);
+ _apply_resolution_constraint(resolution, *c);
}
else
{
@@ -194,12 +191,11 @@ Decider::_resolve_dependents()
const std::tr1::shared_ptr<ConstraintSequence>
Decider::_make_constraints_for_dependent(
- const Resolvent & resolvent,
const std::tr1::shared_ptr<const Resolution> & resolution,
const std::tr1::shared_ptr<const PackageID> & id,
const std::tr1::shared_ptr<const PackageIDSequence> & r) const
{
- return _imp->fns.get_constraints_for_dependent_fn()(resolvent, resolution, id, r);
+ return _imp->fns.get_constraints_for_dependent_fn()(resolution, id, r);
}
namespace
@@ -341,11 +337,11 @@ Decider::_collect_changing() const
{
ChangingCollector c;
- for (ResolutionsByResolventMap::const_iterator i(_imp->resolutions_by_resolvent.begin()),
- i_end(_imp->resolutions_by_resolvent.end()) ;
+ for (ResolutionsByResolvent::ConstIterator i(_imp->resolutions_by_resolvent->begin()),
+ i_end(_imp->resolutions_by_resolvent->end()) ;
i != i_end ; ++i)
- if (i->second->decision())
- i->second->decision()->accept(c);
+ if ((*i)->decision())
+ (*i)->decision()->accept(c);
return std::make_pair(c.going_away, c.newly_available);
}
@@ -371,10 +367,21 @@ Decider::_resolve_destinations()
{
Context context("When resolving destinations:");
- for (ResolutionsByResolventMap::iterator i(_imp->resolutions_by_resolvent.begin()),
- i_end(_imp->resolutions_by_resolvent.end()) ;
+ for (ResolutionsByResolvent::ConstIterator i(_imp->resolutions_by_resolvent->begin()),
+ i_end(_imp->resolutions_by_resolvent->end()) ;
+ i != i_end ; ++i)
+ _do_destination_if_necessary(*i);
+}
+
+void
+Decider::_resolve_confirmations()
+{
+ Context context("When resolving confirmations:");
+
+ for (ResolutionsByResolvent::ConstIterator i(_imp->resolutions_by_resolvent->begin()),
+ i_end(_imp->resolutions_by_resolvent->end()) ;
i != i_end ; ++i)
- _do_destination_if_necessary(i->first, i->second);
+ _confirm(*i);
}
namespace
@@ -424,23 +431,21 @@ namespace
void
Decider::_do_destination_if_necessary(
- const Resolvent & resolvent,
const std::tr1::shared_ptr<Resolution> & resolution)
{
DoDestinationIfNecessaryVisitor v(
- std::tr1::bind(&Decider::_make_destination_for, this, resolvent, resolution, std::tr1::placeholders::_1),
- std::tr1::bind(&Decider::_make_change_type_for, this, resolvent, resolution, std::tr1::placeholders::_1)
+ std::tr1::bind(&Decider::_make_destination_for, this, resolution, std::tr1::placeholders::_1),
+ std::tr1::bind(&Decider::_make_change_type_for, this, resolution, std::tr1::placeholders::_1)
);
resolution->decision()->accept(v);
}
const std::tr1::shared_ptr<Destination>
Decider::_make_destination_for(
- const Resolvent & resolvent,
const std::tr1::shared_ptr<const Resolution> & resolution,
const ChangesToMakeDecision & decision) const
{
- const std::tr1::shared_ptr<const Repository> repo(_find_repository_for(resolvent, resolution, decision));
+ const std::tr1::shared_ptr<const Repository> repo(_find_repository_for(resolution, decision));
if ((! repo->destination_interface()) ||
(! repo->destination_interface()->is_suitable_destination_for(*decision.origin_id())))
throw InternalError(PALUDIS_HERE, stringify(repo->name()) + " is not a suitable destination for "
@@ -454,7 +459,6 @@ Decider::_make_destination_for(
const ChangeType
Decider::_make_change_type_for(
- const Resolvent &,
const std::tr1::shared_ptr<const Resolution> &,
const ChangesToMakeDecision & decision) const
{
@@ -491,11 +495,11 @@ Decider::_make_change_type_for(
}
const std::tr1::shared_ptr<const Repository>
-Decider::_find_repository_for(const Resolvent & resolvent,
+Decider::_find_repository_for(
const std::tr1::shared_ptr<const Resolution> & resolution,
const ChangesToMakeDecision & decision) const
{
- return _imp->fns.find_repository_for_fn()(resolvent, resolution, decision);
+ return _imp->fns.find_repository_for_fn()(resolution, decision);
}
FilteredGenerator
@@ -567,37 +571,25 @@ Decider::_create_resolution_for_resolvent(const Resolvent & r) const
const std::tr1::shared_ptr<Resolution>
Decider::_resolution_for_resolvent(const Resolvent & r, const bool create)
{
- ResolutionsByResolventMap::iterator i(_imp->resolutions_by_resolvent.find(r));
- if (_imp->resolutions_by_resolvent.end() == i)
+ ResolutionsByResolvent::ConstIterator i(_imp->resolutions_by_resolvent->find(r));
+ if (_imp->resolutions_by_resolvent->end() == i)
{
if (create)
{
std::tr1::shared_ptr<Resolution> resolution(_create_resolution_for_resolvent(r));
- i = _imp->resolutions_by_resolvent.insert(std::make_pair(r, resolution)).first;
- _imp->lists->all_resolutions()->append(resolution);
+ i = _imp->resolutions_by_resolvent->insert_new(resolution);
}
else
throw InternalError(PALUDIS_HERE, "resolver bug: expected resolution for "
+ stringify(r) + " to exist, but it doesn't");
}
- return i->second;
-}
-
-const std::tr1::shared_ptr<Resolution>
-Decider::resolution_for_resolvent(const Resolvent & r) const
-{
- ResolutionsByResolventMap::const_iterator i(_imp->resolutions_by_resolvent.find(r));
- if (_imp->resolutions_by_resolvent.end() == i)
- throw InternalError(PALUDIS_HERE, "resolver bug: expected resolution for "
- + stringify(r) + " to exist, but it doesn't");
-
- return i->second;
+ return *i;
}
const std::tr1::shared_ptr<ConstraintSequence>
Decider::_make_constraints_from_target(
- const Resolvent & resolvent,
+ const std::tr1::shared_ptr<const Resolution> & resolution,
const PackageOrBlockDepSpec & spec,
const std::tr1::shared_ptr<const Reason> & reason) const
{
@@ -605,23 +597,25 @@ Decider::_make_constraints_from_target(
{
const std::tr1::shared_ptr<ConstraintSequence> result(new ConstraintSequence);
result->push_back(make_shared_ptr(new Constraint(make_named_values<Constraint>(
- n::destination_type() = resolvent.destination_type(),
+ n::destination_type() = resolution->resolvent().destination_type(),
n::nothing_is_fine_too() = false,
n::reason() = reason,
n::spec() = spec,
n::untaken() = false,
- n::use_existing() = _imp->fns.get_use_existing_fn()(resolvent, *spec.if_package(), reason)
+ n::use_existing() = _imp->fns.get_use_existing_fn()(resolution, *spec.if_package(), reason)
))));
return result;
}
else if (spec.if_block())
- return _make_constraints_from_blocker(resolvent, *spec.if_block(), reason);
+ return _make_constraints_from_blocker(resolution, *spec.if_block(), reason);
else
throw InternalError(PALUDIS_HERE, "resolver bug: huh? it's not a block and it's not a package");
}
const std::tr1::shared_ptr<ConstraintSequence>
-Decider::_make_constraints_from_dependency(const Resolvent & resolvent, const SanitisedDependency & dep,
+Decider::_make_constraints_from_dependency(
+ const std::tr1::shared_ptr<const Resolution> & resolution,
+ const SanitisedDependency & dep,
const std::tr1::shared_ptr<const Reason> & reason,
const SpecInterest interest) const
{
@@ -629,25 +623,24 @@ Decider::_make_constraints_from_dependency(const Resolvent & resolvent, const Sa
{
const std::tr1::shared_ptr<ConstraintSequence> result(new ConstraintSequence);
result->push_back(make_shared_ptr(new Constraint(make_named_values<Constraint>(
- n::destination_type() = resolvent.destination_type(),
+ n::destination_type() = resolution->resolvent().destination_type(),
n::nothing_is_fine_too() = false,
n::reason() = reason,
n::spec() = *dep.spec().if_package(),
n::untaken() = si_untaken == interest,
- n::use_existing() = _imp->fns.get_use_existing_fn()(
- resolvent, *dep.spec().if_package(), reason)
+ n::use_existing() = _imp->fns.get_use_existing_fn()(resolution, *dep.spec().if_package(), reason)
))));
return result;
}
else if (dep.spec().if_block())
- return _make_constraints_from_blocker(resolvent, *dep.spec().if_block(), reason);
+ return _make_constraints_from_blocker(resolution, *dep.spec().if_block(), reason);
else
throw InternalError(PALUDIS_HERE, "resolver bug: huh? it's not a block and it's not a package");
}
const std::tr1::shared_ptr<ConstraintSequence>
Decider::_make_constraints_from_blocker(
- const Resolvent &,
+ const std::tr1::shared_ptr<const Resolution> &,
const BlockDepSpec & spec,
const std::tr1::shared_ptr<const Reason> & reason) const
{
@@ -670,13 +663,12 @@ Decider::_make_constraints_from_blocker(
void
Decider::_apply_resolution_constraint(
- const Resolvent & resolvent,
const std::tr1::shared_ptr<Resolution> & resolution,
const std::tr1::shared_ptr<const Constraint> & constraint)
{
if (resolution->decision())
- if (! _verify_new_constraint(resolvent, resolution, constraint))
- _made_wrong_decision(resolvent, resolution, constraint);
+ if (! _verify_new_constraint(resolution, constraint))
+ _made_wrong_decision(resolution, constraint);
resolution->constraints()->add(constraint);
}
@@ -799,7 +791,7 @@ namespace
}
bool
-Decider::_check_constraint(const Resolvent &,
+Decider::_check_constraint(
const std::tr1::shared_ptr<const Constraint> & constraint,
const std::tr1::shared_ptr<const Decision> & decision) const
{
@@ -819,11 +811,11 @@ Decider::_check_constraint(const Resolvent &,
}
bool
-Decider::_verify_new_constraint(const Resolvent & resolvent,
+Decider::_verify_new_constraint(
const std::tr1::shared_ptr<const Resolution> & resolution,
const std::tr1::shared_ptr<const Constraint> & constraint)
{
- return _check_constraint(resolvent, constraint, resolution->decision());
+ return _check_constraint(constraint, resolution->decision());
}
namespace
@@ -865,7 +857,7 @@ namespace
}
void
-Decider::_made_wrong_decision(const Resolvent & resolvent,
+Decider::_made_wrong_decision(
const std::tr1::shared_ptr<Resolution> & resolution,
const std::tr1::shared_ptr<const Constraint> & constraint)
{
@@ -873,30 +865,29 @@ Decider::_made_wrong_decision(const Resolvent & resolvent,
std::tr1::shared_ptr<Resolution> adapted_resolution(make_shared_ptr(new Resolution(*resolution)));
adapted_resolution->constraints()->add(constraint);
- const std::tr1::shared_ptr<Decision> decision(_try_to_find_decision_for(resolvent, adapted_resolution));
+ const std::tr1::shared_ptr<Decision> decision(_try_to_find_decision_for(adapted_resolution));
if (decision)
{
resolution->decision()->accept(WrongDecisionVisitor(std::tr1::bind(
- &Decider::_suggest_restart_with, this, resolvent, resolution, constraint, decision)));
+ &Decider::_suggest_restart_with, this, resolution, constraint, decision)));
resolution->decision() = decision;
}
else
- resolution->decision() = _cannot_decide_for(resolvent, adapted_resolution);
+ resolution->decision() = _cannot_decide_for(adapted_resolution);
}
void
-Decider::_suggest_restart_with(const Resolvent & resolvent,
+Decider::_suggest_restart_with(
const std::tr1::shared_ptr<const Resolution> & resolution,
const std::tr1::shared_ptr<const Constraint> & constraint,
const std::tr1::shared_ptr<const Decision> & decision) const
{
- throw SuggestRestart(resolvent, resolution->decision(), constraint, decision,
- _make_constraint_for_preloading(resolvent, decision, constraint));
+ throw SuggestRestart(resolution->resolvent(), resolution->decision(), constraint, decision,
+ _make_constraint_for_preloading(decision, constraint));
}
const std::tr1::shared_ptr<const Constraint>
Decider::_make_constraint_for_preloading(
- const Resolvent &,
const std::tr1::shared_ptr<const Decision> &,
const std::tr1::shared_ptr<const Constraint> & c) const
{
@@ -935,15 +926,15 @@ Decider::_make_spec_for_preloading(const PackageDepSpec & spec) const
}
void
-Decider::_decide(const Resolvent & resolvent, const std::tr1::shared_ptr<Resolution> & resolution)
+Decider::_decide(const std::tr1::shared_ptr<Resolution> & resolution)
{
- Context context("When deciding upon an origin ID to use for '" + stringify(resolvent) + "':");
+ Context context("When deciding upon an origin ID to use for '" + stringify(resolution->resolvent()) + "':");
- std::tr1::shared_ptr<Decision> decision(_try_to_find_decision_for(resolvent, resolution));
+ std::tr1::shared_ptr<Decision> decision(_try_to_find_decision_for(resolution));
if (decision)
resolution->decision() = decision;
else
- resolution->decision() = _cannot_decide_for(resolvent, resolution);
+ resolution->decision() = _cannot_decide_for(resolution);
}
namespace
@@ -985,7 +976,6 @@ namespace
void
Decider::_add_dependencies_if_necessary(
- const Resolvent & our_resolvent,
const std::tr1::shared_ptr<Resolution> & our_resolution)
{
const std::tr1::shared_ptr<const PackageID> package_id(
@@ -994,18 +984,18 @@ Decider::_add_dependencies_if_necessary(
if (! package_id)
return;
- Context context("When adding dependencies for '" + stringify(our_resolvent) + "' with '"
+ Context context("When adding dependencies for '" + stringify(our_resolution->resolvent()) + "' with '"
+ stringify(*package_id) + "':");
const std::tr1::shared_ptr<SanitisedDependencies> deps(new SanitisedDependencies);
- deps->populate(*this, our_resolvent, package_id);
+ deps->populate(*this, our_resolution, package_id);
for (SanitisedDependencies::ConstIterator s(deps->begin()), s_end(deps->end()) ;
s != s_end ; ++s)
{
Context context_2("When handling dependency '" + stringify(s->spec()) + "':");
- SpecInterest interest(_interest_in_spec(our_resolvent, our_resolution, *s));
+ SpecInterest interest(_interest_in_spec(our_resolution, *s));
switch (interest)
{
@@ -1019,7 +1009,7 @@ Decider::_add_dependencies_if_necessary(
}
const std::tr1::shared_ptr<DependencyReason> reason(new DependencyReason(
- package_id, our_resolvent, *s, _already_met(*s)));
+ package_id, our_resolution->resolvent(), *s, _already_met(*s)));
std::tr1::shared_ptr<const Resolvents> resolvents;
@@ -1042,21 +1032,19 @@ Decider::_add_dependencies_if_necessary(
r != r_end ; ++r)
{
const std::tr1::shared_ptr<Resolution> dep_resolution(_resolution_for_resolvent(*r, true));
- const std::tr1::shared_ptr<ConstraintSequence> constraints(_make_constraints_from_dependency(
- our_resolvent, *s, reason, interest));
+ const std::tr1::shared_ptr<ConstraintSequence> constraints(_make_constraints_from_dependency(our_resolution, *s, reason, interest));
for (ConstraintSequence::ConstIterator c(constraints->begin()), c_end(constraints->end()) ;
c != c_end ; ++c)
- _apply_resolution_constraint(*r, dep_resolution, *c);
+ _apply_resolution_constraint(dep_resolution, *c);
}
}
}
SpecInterest
-Decider::_interest_in_spec(const Resolvent & resolvent,
- const std::tr1::shared_ptr<const Resolution> & resolution, const SanitisedDependency & dep) const
+Decider::_interest_in_spec(const std::tr1::shared_ptr<const Resolution> & resolution, const SanitisedDependency & dep) const
{
- return _imp->fns.interest_in_spec_fn()(resolvent, resolution, dep);
+ return _imp->fns.interest_in_spec_fn()(resolution, dep);
}
const std::tr1::shared_ptr<Constraints>
@@ -1097,10 +1085,10 @@ namespace
}
std::pair<AnyChildScore, OperatorScore>
-Decider::find_any_score(const Resolvent & our_resolvent, const SanitisedDependency & dep) const
+Decider::find_any_score(const std::tr1::shared_ptr<const Resolution> & our_resolution, const SanitisedDependency & dep) const
{
Context context("When working out whether we'd like '" + stringify(dep.spec()) + "' because of '"
- + stringify(our_resolvent) + "':");
+ + stringify(our_resolution->resolvent()) + "':");
if (dep.spec().if_block())
throw InternalError(PALUDIS_HERE, "unimplemented: blockers inside || blocks are horrid");
@@ -1200,13 +1188,12 @@ Decider::find_any_score(const Resolvent & our_resolvent, const SanitisedDependen
return std::make_pair(acs_wrong_options_installed, operator_bias);
}
- const std::tr1::shared_ptr<const PackageID> id(resolution_for_resolvent(
- our_resolvent)->decision()->accept_returning<std::tr1::shared_ptr<const PackageID> >(
- ChosenIDVisitor()));
+ const std::tr1::shared_ptr<const PackageID> id(
+ our_resolution->decision()->accept_returning<std::tr1::shared_ptr<const PackageID> >(ChosenIDVisitor()));
if (! id)
throw InternalError(PALUDIS_HERE, "resolver bug: why don't we have an id?");
- const std::tr1::shared_ptr<DependencyReason> reason(new DependencyReason(id, our_resolvent, dep, _already_met(dep)));
+ const std::tr1::shared_ptr<DependencyReason> reason(new DependencyReason(id, our_resolution->resolvent(), dep, _already_met(dep)));
const std::tr1::shared_ptr<const Resolvents> resolvents(_get_resolvents_for(spec, reason));
/* next: will already be installing */
@@ -1214,8 +1201,8 @@ Decider::find_any_score(const Resolvent & our_resolvent, const SanitisedDependen
for (Resolvents::ConstIterator r(resolvents->begin()), r_end(resolvents->end()) ;
r != r_end ; ++r)
{
- ResolutionsByResolventMap::const_iterator i(_imp->resolutions_by_resolvent.find(*r));
- if (i != _imp->resolutions_by_resolvent.end())
+ ResolutionsByResolvent::ConstIterator i(_imp->resolutions_by_resolvent->find(*r));
+ if (i != _imp->resolutions_by_resolvent->end())
return std::make_pair(acs_will_be_installing, operator_bias);
}
}
@@ -1227,11 +1214,11 @@ Decider::find_any_score(const Resolvent & our_resolvent, const SanitisedDependen
{
const std::tr1::shared_ptr<Resolution> resolution(_create_resolution_for_resolvent(*r));
const std::tr1::shared_ptr<ConstraintSequence> constraints(_make_constraints_from_dependency(
- our_resolvent, dep, reason, si_take));
+ our_resolution, dep, reason, si_take));
for (ConstraintSequence::ConstIterator c(constraints->begin()), c_end(constraints->end()) ;
c != c_end ; ++c)
resolution->constraints()->add(*c);
- const std::tr1::shared_ptr<Decision> decision(_try_to_find_decision_for(*r, resolution));
+ const std::tr1::shared_ptr<Decision> decision(_try_to_find_decision_for(resolution));
if (decision)
return std::make_pair(acs_could_install, operator_bias);
}
@@ -1356,22 +1343,21 @@ Decider::_get_error_resolvents_for(
const std::tr1::shared_ptr<Decision>
Decider::_try_to_find_decision_for(
- const Resolvent & resolvent,
const std::tr1::shared_ptr<const Resolution> & resolution) const
{
- const std::tr1::shared_ptr<const PackageID> existing_id(_find_existing_id_for(resolvent, resolution));
- std::pair<const std::tr1::shared_ptr<const PackageID>, bool> installable_id_best(_find_installable_id_for(resolvent, resolution));
+ const std::tr1::shared_ptr<const PackageID> existing_id(_find_existing_id_for(resolution));
+ std::pair<const std::tr1::shared_ptr<const PackageID>, bool> installable_id_best(_find_installable_id_for(resolution));
const std::tr1::shared_ptr<const PackageID> installable_id(installable_id_best.first);
bool best(installable_id_best.second);
if (resolution->constraints()->nothing_is_fine_too())
{
- const std::tr1::shared_ptr<const PackageIDSequence> existing_resolvent_ids(_installed_ids(resolvent));
+ const std::tr1::shared_ptr<const PackageIDSequence> existing_resolvent_ids(_installed_ids(resolution->resolvent()));
if (existing_resolvent_ids->empty())
{
/* nothing existing, but nothing's ok */
return make_shared_ptr(new NothingNoChangeDecision(
- resolvent,
+ resolution->resolvent(),
! resolution->constraints()->all_untaken()
));
}
@@ -1382,7 +1368,7 @@ Decider::_try_to_find_decision_for(
/* there's nothing suitable existing. we fix the last_ct when we do
* destinations. */
return make_shared_ptr(new ChangesToMakeDecision(
- resolvent,
+ resolution->resolvent(),
installable_id,
best,
last_ct,
@@ -1416,7 +1402,7 @@ Decider::_try_to_find_decision_for(
}
return make_shared_ptr(new ExistingNoChangeDecision(
- resolvent,
+ resolution->resolvent(),
existing_id,
true,
true,
@@ -1429,10 +1415,10 @@ Decider::_try_to_find_decision_for(
/* we can't stick with our existing id, if there is one, and we can't
* fix it by installing things. this might be an error, or we might be
* able to remove things. */
- if (resolution->constraints()->nothing_is_fine_too() && _installed_but_allowed_to_remove(resolvent))
+ if (resolution->constraints()->nothing_is_fine_too() && _installed_but_allowed_to_remove(resolution->resolvent()))
return make_shared_ptr(new RemoveDecision(
- resolvent,
- _installed_ids(resolvent),
+ resolution->resolvent(),
+ _installed_ids(resolution->resolvent()),
! resolution->constraints()->all_untaken()
));
else
@@ -1498,7 +1484,7 @@ Decider::_try_to_find_decision_for(
/* we've got existing and installable. do we have any reason not to pick the existing id? */
const std::tr1::shared_ptr<Decision> existing(new ExistingNoChangeDecision(
- resolvent,
+ resolution->resolvent(),
existing_id,
is_same,
is_same_version,
@@ -1506,7 +1492,7 @@ Decider::_try_to_find_decision_for(
! resolution->constraints()->all_untaken()
));
const std::tr1::shared_ptr<Decision> changes_to_make(new ChangesToMakeDecision(
- resolvent,
+ resolution->resolvent(),
installable_id,
best,
last_ct,
@@ -1519,7 +1505,7 @@ Decider::_try_to_find_decision_for(
case ue_only_if_transient:
case ue_never:
return make_shared_ptr(new ChangesToMakeDecision(
- resolvent,
+ resolution->resolvent(),
installable_id,
best,
last_ct,
@@ -1552,22 +1538,21 @@ Decider::_try_to_find_decision_for(
const std::tr1::shared_ptr<Decision>
Decider::_cannot_decide_for(
- const Resolvent & resolvent,
const std::tr1::shared_ptr<const Resolution> & resolution) const
{
const std::tr1::shared_ptr<UnsuitableCandidates> unsuitable_candidates(new UnsuitableCandidates);
- const std::tr1::shared_ptr<const PackageID> existing_id(_find_existing_id_for(resolvent, resolution));
+ const std::tr1::shared_ptr<const PackageID> existing_id(_find_existing_id_for(resolution));
if (existing_id)
- unsuitable_candidates->push_back(_make_unsuitable_candidate(resolvent, resolution, existing_id, true));
+ unsuitable_candidates->push_back(_make_unsuitable_candidate(resolution, existing_id, true));
- const std::tr1::shared_ptr<const PackageIDSequence> installable_ids(_find_installable_id_candidates_for(resolvent, resolution, true));
+ const std::tr1::shared_ptr<const PackageIDSequence> installable_ids(_find_installable_id_candidates_for(resolution, true));
for (PackageIDSequence::ConstIterator i(installable_ids->begin()), i_end(installable_ids->end()) ;
i != i_end ; ++i)
- unsuitable_candidates->push_back(_make_unsuitable_candidate(resolvent, resolution, *i, false));
+ unsuitable_candidates->push_back(_make_unsuitable_candidate(resolution, *i, false));
return make_shared_ptr(new UnableToMakeDecision(
- resolvent,
+ resolution->resolvent(),
unsuitable_candidates,
! resolution->constraints()->all_untaken()
));
@@ -1575,22 +1560,21 @@ Decider::_cannot_decide_for(
UnsuitableCandidate
Decider::_make_unsuitable_candidate(
- const Resolvent & resolvent,
- const std::tr1::shared_ptr<const Resolution> &,
+ const std::tr1::shared_ptr<const Resolution> & resolution,
const std::tr1::shared_ptr<const PackageID> & id,
const bool existing) const
{
return make_named_values<UnsuitableCandidate>(
n::package_id() = id,
- n::unmet_constraints() = _get_unmatching_constraints(resolvent, id, existing)
+ n::unmet_constraints() = _get_unmatching_constraints(resolution, id, existing)
);
}
const std::tr1::shared_ptr<const PackageID>
-Decider::_find_existing_id_for(const Resolvent & resolvent, const std::tr1::shared_ptr<const Resolution> & resolution) const
+Decider::_find_existing_id_for(const std::tr1::shared_ptr<const Resolution> & resolution) const
{
- const std::tr1::shared_ptr<const PackageIDSequence> ids(_installed_ids(resolvent));
- return _find_id_for_from(resolvent, resolution, ids).first;
+ const std::tr1::shared_ptr<const PackageIDSequence> ids(_installed_ids(resolution->resolvent()));
+ return _find_id_for_from(resolution, ids).first;
}
bool
@@ -1632,27 +1616,27 @@ Decider::_installed_ids(const Resolvent & resolvent) const
}
const std::tr1::shared_ptr<const PackageIDSequence>
-Decider::_find_installable_id_candidates_for(const Resolvent & resolvent,
- const std::tr1::shared_ptr<const Resolution> &,
+Decider::_find_installable_id_candidates_for(
+ const std::tr1::shared_ptr<const Resolution> & resolution,
const bool include_errors) const
{
return (*_imp->env)[selection::AllVersionsSorted(
- generator::Package(resolvent.package()) |
- make_slot_filter(resolvent) |
+ generator::Package(resolution->resolvent().package()) |
+ make_slot_filter(resolution->resolvent()) |
filter::SupportsAction<InstallAction>() |
((! include_errors) ? Filter(filter::NotMasked()) : Filter(filter::All()))
)];
}
const std::pair<const std::tr1::shared_ptr<const PackageID>, bool>
-Decider::_find_installable_id_for(const Resolvent & resolvent, const std::tr1::shared_ptr<const Resolution> & resolution) const
+Decider::_find_installable_id_for(const std::tr1::shared_ptr<const Resolution> & resolution) const
{
- return _find_id_for_from(resolvent, resolution, _find_installable_id_candidates_for(resolvent, resolution, false));
+ return _find_id_for_from(resolution, _find_installable_id_candidates_for(resolution, false));
}
const std::pair<const std::tr1::shared_ptr<const PackageID>, bool>
Decider::_find_id_for_from(
- const Resolvent &, const std::tr1::shared_ptr<const Resolution> & resolution,
+ const std::tr1::shared_ptr<const Resolution> & resolution,
const std::tr1::shared_ptr<const PackageIDSequence> & ids) const
{
bool best(true);
@@ -1684,11 +1668,10 @@ Decider::_find_id_for_from(
const std::tr1::shared_ptr<const Constraints>
Decider::_get_unmatching_constraints(
- const Resolvent & resolvent,
+ const std::tr1::shared_ptr<const Resolution> & resolution,
const std::tr1::shared_ptr<const PackageID> & id,
const bool existing) const
{
- const std::tr1::shared_ptr<const Resolution> resolution(resolution_for_resolvent(resolvent));
const std::tr1::shared_ptr<Constraints> result(new Constraints);
for (Constraints::ConstIterator c(resolution->constraints()->begin()),
@@ -1702,7 +1685,7 @@ Decider::_get_unmatching_constraints(
bool is_transient(id->behaviours_key() && id->behaviours_key()->value()->end() !=
id->behaviours_key()->value()->find("transient"));
decision.reset(new ExistingNoChangeDecision(
- resolvent,
+ resolution->resolvent(),
id,
true,
true,
@@ -1712,14 +1695,14 @@ Decider::_get_unmatching_constraints(
}
else
decision.reset(new ChangesToMakeDecision(
- resolvent,
+ resolution->resolvent(),
id,
false,
last_ct,
! (*c)->untaken(),
make_null_shared_ptr()
));
- if (! _check_constraint(resolvent, *c, decision))
+ if (! _check_constraint(*c, decision))
result->add(*c);
}
@@ -1772,11 +1755,11 @@ Decider::add_target_with_reason(const PackageOrBlockDepSpec & spec, const std::t
+ stringify(*r) + "':");
const std::tr1::shared_ptr<Resolution> dep_resolution(_resolution_for_resolvent(*r, true));
- const std::tr1::shared_ptr<ConstraintSequence> constraints(_make_constraints_from_target(*r, spec, reason));
+ const std::tr1::shared_ptr<ConstraintSequence> constraints(_make_constraints_from_target(dep_resolution, spec, reason));
for (ConstraintSequence::ConstIterator c(constraints->begin()), c_end(constraints->end()) ;
c != c_end ; ++c)
- _apply_resolution_constraint(*r, dep_resolution, *c);
+ _apply_resolution_constraint(dep_resolution, *c);
}
}
}
@@ -1795,6 +1778,9 @@ Decider::resolve()
_imp->env->trigger_notifier_callback(NotifierCallbackResolverStageEvent("Finding Destinations"));
_resolve_destinations();
+
+ _imp->env->trigger_notifier_callback(NotifierCallbackResolverStageEvent("Confirming"));
+ _resolve_confirmations();
}
bool
@@ -1812,3 +1798,27 @@ Decider::_already_met(const SanitisedDependency & dep) const
return dep.spec().if_package();
}
+void
+Decider::_confirm(
+ const std::tr1::shared_ptr<const Resolution> & resolution)
+{
+ ChangesToMakeDecision * const changes_to_make_decision(simple_visitor_cast<ChangesToMakeDecision>(*resolution->decision()));
+ if (! changes_to_make_decision)
+ return;
+
+ if (! changes_to_make_decision->best())
+ {
+ const std::tr1::shared_ptr<RequiredConfirmation> c(new NotBestConfirmation);
+ if (! _imp->fns.confirm_fn()(resolution, c))
+ changes_to_make_decision->add_required_confirmation(c);
+ }
+
+ if (ct_downgrade == changes_to_make_decision->change_type())
+ {
+ const std::tr1::shared_ptr<DowngradeConfirmation> c(new DowngradeConfirmation);
+ if (! _imp->fns.confirm_fn()(resolution, c))
+ changes_to_make_decision->add_required_confirmation(c);
+ }
+}
+
+
diff --git a/paludis/resolver/decider.hh b/paludis/resolver/decider.hh
index 379d166..ff9d161 100644
--- a/paludis/resolver/decider.hh
+++ b/paludis/resolver/decider.hh
@@ -31,12 +31,12 @@
#include <paludis/resolver/destination-fwd.hh>
#include <paludis/resolver/unsuitable_candidates-fwd.hh>
#include <paludis/resolver/spec_rewriter-fwd.hh>
-#include <paludis/resolver/resolutions-fwd.hh>
#include <paludis/resolver/resolver_functions-fwd.hh>
#include <paludis/resolver/resolver-fwd.hh>
#include <paludis/resolver/any_child_score-fwd.hh>
#include <paludis/resolver/change_type-fwd.hh>
#include <paludis/resolver/package_or_block_dep_spec-fwd.hh>
+#include <paludis/resolver/resolutions_by_resolvent-fwd.hh>
#include <paludis/util/attributes.hh>
#include <paludis/util/private_implementation_pattern.hh>
#include <paludis/dep_spec-fwd.hh>
@@ -74,48 +74,48 @@ namespace paludis
const std::tr1::shared_ptr<const Reason> & reason) const;
const std::tr1::shared_ptr<ConstraintSequence> _make_constraints_from_target(
- const Resolvent &,
+ const std::tr1::shared_ptr<const Resolution> &,
const PackageOrBlockDepSpec &,
const std::tr1::shared_ptr<const Reason> &) const;
const std::tr1::shared_ptr<ConstraintSequence> _make_constraints_from_dependency(
- const Resolvent &, const SanitisedDependency &,
+ const std::tr1::shared_ptr<const Resolution> &,
+ const SanitisedDependency &,
const std::tr1::shared_ptr<const Reason> &,
const SpecInterest) const;
const std::tr1::shared_ptr<ConstraintSequence> _make_constraints_from_blocker(
- const Resolvent & resolvent, const BlockDepSpec & dep,
+ const std::tr1::shared_ptr<const Resolution> &,
+ const BlockDepSpec & dep,
const std::tr1::shared_ptr<const Reason> & reason) const;
const std::tr1::shared_ptr<ConstraintSequence> _make_constraints_for_dependent(
- const Resolvent &,
const std::tr1::shared_ptr<const Resolution> & resolution,
const std::tr1::shared_ptr<const PackageID> &,
const std::tr1::shared_ptr<const PackageIDSequence> &) const;
- void _apply_resolution_constraint(const Resolvent &,
+ void _apply_resolution_constraint(
const std::tr1::shared_ptr<Resolution> &,
const std::tr1::shared_ptr<const Constraint> &);
- bool _check_constraint(const Resolvent &,
+ bool _check_constraint(
const std::tr1::shared_ptr<const Constraint> & constraint,
const std::tr1::shared_ptr<const Decision> & decision) const;
- bool _verify_new_constraint(const Resolvent &,
+ bool _verify_new_constraint(
const std::tr1::shared_ptr<const Resolution> &,
const std::tr1::shared_ptr<const Constraint> &);
- void _made_wrong_decision(const Resolvent &,
+ void _made_wrong_decision(
const std::tr1::shared_ptr<Resolution> & resolution,
const std::tr1::shared_ptr<const Constraint> & constraint);
- void _suggest_restart_with(const Resolvent &,
+ void _suggest_restart_with(
const std::tr1::shared_ptr<const Resolution> & resolution,
const std::tr1::shared_ptr<const Constraint> & constraint,
const std::tr1::shared_ptr<const Decision> & decision) const PALUDIS_ATTRIBUTE((noreturn));
const std::tr1::shared_ptr<const Constraint> _make_constraint_for_preloading(
- const Resolvent &,
const std::tr1::shared_ptr<const Decision> & d,
const std::tr1::shared_ptr<const Constraint> & c) const;
@@ -126,42 +126,39 @@ namespace paludis
const std::tr1::shared_ptr<const Repository> &) const;
const std::tr1::shared_ptr<const Repository> _find_repository_for(
- const Resolvent &,
const std::tr1::shared_ptr<const Resolution> &,
const ChangesToMakeDecision &) const;
void _resolve_decide_with_dependencies();
bool _resolve_dependents() PALUDIS_ATTRIBUTE((warn_unused_result));
void _resolve_destinations();
+ void _resolve_confirmations();
const std::tr1::shared_ptr<Destination> _make_destination_for(
- const Resolvent & resolvent,
const std::tr1::shared_ptr<const Resolution> & resolution,
const ChangesToMakeDecision &) const;
const ChangeType _make_change_type_for(
- const Resolvent & resolvent,
const std::tr1::shared_ptr<const Resolution> & resolution,
const ChangesToMakeDecision &) const;
FilteredGenerator _make_destination_filtered_generator(const Generator &, const Resolvent & resolvent) const;
- void _decide(const Resolvent &, const std::tr1::shared_ptr<Resolution> & resolution);
+ void _decide(const std::tr1::shared_ptr<Resolution> & resolution);
const std::tr1::shared_ptr<Decision> _try_to_find_decision_for(
- const Resolvent &, const std::tr1::shared_ptr<const Resolution> & resolution) const;
+ const std::tr1::shared_ptr<const Resolution> & resolution) const;
const std::tr1::shared_ptr<Decision> _cannot_decide_for(
- const Resolvent &, const std::tr1::shared_ptr<const Resolution> & resolution) const;
+ const std::tr1::shared_ptr<const Resolution> & resolution) const;
- void _do_destination_if_necessary(const Resolvent & our_resolvent,
+ void _do_destination_if_necessary(
const std::tr1::shared_ptr<Resolution> & our_resolution);
- void _add_dependencies_if_necessary(const Resolvent & our_resolvent,
+ void _add_dependencies_if_necessary(
const std::tr1::shared_ptr<Resolution> & our_resolution);
SpecInterest _interest_in_spec(
- const Resolvent &,
const std::tr1::shared_ptr<const Resolution> &,
const SanitisedDependency &) const;
@@ -171,23 +168,22 @@ namespace paludis
const std::tr1::shared_ptr<const PackageID> & b) const;
const std::tr1::shared_ptr<const PackageID> _find_existing_id_for(
- const Resolvent &, const std::tr1::shared_ptr<const Resolution> &) const;
+ const std::tr1::shared_ptr<const Resolution> &) const;
const std::tr1::shared_ptr<const PackageIDSequence> _find_installable_id_candidates_for(
- const Resolvent &, const std::tr1::shared_ptr<const Resolution> &,
+ const std::tr1::shared_ptr<const Resolution> &,
const bool include_errors) const;
const std::pair<const std::tr1::shared_ptr<const PackageID>, bool> _find_installable_id_for(
- const Resolvent &, const std::tr1::shared_ptr<const Resolution> &) const;
+ const std::tr1::shared_ptr<const Resolution> &) const;
const std::pair<const std::tr1::shared_ptr<const PackageID>, bool> _find_id_for_from(
- const Resolvent &, const std::tr1::shared_ptr<const Resolution> &,
+ const std::tr1::shared_ptr<const Resolution> &,
const std::tr1::shared_ptr<const PackageIDSequence> &) const;
const std::tr1::shared_ptr<const Constraints> _get_unmatching_constraints(
- const Resolvent &,
+ const std::tr1::shared_ptr<const Resolution> &,
const std::tr1::shared_ptr<const PackageID> &,
const bool existing) const PALUDIS_ATTRIBUTE((warn_unused_result));
UnsuitableCandidate _make_unsuitable_candidate(
- const Resolvent &,
const std::tr1::shared_ptr<const Resolution> &,
const std::tr1::shared_ptr<const PackageID> &,
const bool existing) const;
@@ -217,22 +213,23 @@ namespace paludis
const std::tr1::shared_ptr<const PackageIDSequence> &,
const std::tr1::shared_ptr<const PackageIDSequence> &) const PALUDIS_ATTRIBUTE((warn_unused_result));
+ void _confirm(const std::tr1::shared_ptr<const Resolution> & resolution);
+
public:
Decider(const Environment * const,
const ResolverFunctions &,
- const std::tr1::shared_ptr<ResolverLists> &);
+ const std::tr1::shared_ptr<ResolutionsByResolvent> &);
~Decider();
void resolve();
void add_target_with_reason(const PackageOrBlockDepSpec &, const std::tr1::shared_ptr<const Reason> &);
- std::pair<AnyChildScore, OperatorScore> find_any_score(const Resolvent &, const SanitisedDependency &) const;
+ std::pair<AnyChildScore, OperatorScore> find_any_score(
+ const std::tr1::shared_ptr<const Resolution> &, const SanitisedDependency &) const;
const std::tr1::shared_ptr<const RewrittenSpec> rewrite_if_special(const PackageOrBlockDepSpec &,
const std::tr1::shared_ptr<const Resolvent> & maybe_from) const;
-
- const std::tr1::shared_ptr<Resolution> resolution_for_resolvent(const Resolvent &) const;
};
}
}
diff --git a/paludis/resolver/decision.cc b/paludis/resolver/decision.cc
index 5f1473e..ac3e3ba 100644
--- a/paludis/resolver/decision.cc
+++ b/paludis/resolver/decision.cc
@@ -21,6 +21,7 @@
#include <paludis/resolver/destination.hh>
#include <paludis/resolver/unsuitable_candidates.hh>
#include <paludis/resolver/resolvent.hh>
+#include <paludis/resolver/required_confirmations.hh>
#include <paludis/util/make_named_values.hh>
#include <paludis/util/stringify.hh>
#include <paludis/util/private_implementation_pattern-impl.hh>
@@ -79,11 +80,26 @@ Decision::deserialise(Deserialisation & d)
throw InternalError(PALUDIS_HERE, "unknown class '" + stringify(d.class_name()) + "'");
}
+const std::tr1::shared_ptr<ChangeOrRemoveDecision>
+ChangeOrRemoveDecision::deserialise(Deserialisation & d)
+{
+ if (d.class_name() == "ChangesToMakeDecision")
+ {
+ return ChangesToMakeDecision::deserialise(d);
+ }
+ else if (d.class_name() == "RemoveDecision")
+ {
+ return RemoveDecision::deserialise(d);
+ }
+ else
+ throw InternalError(PALUDIS_HERE, "unknown class '" + stringify(d.class_name()) + "'");
+}
+
const std::tr1::shared_ptr<ChangesToMakeDecision>
ChangesToMakeDecision::deserialise(Deserialisation & d)
{
Deserialisator v(d, "ChangesToMakeDecision");
- return make_shared_ptr(new ChangesToMakeDecision(
+ std::tr1::shared_ptr<ChangesToMakeDecision> result(new ChangesToMakeDecision(
v.member<Resolvent>("resolvent"),
v.member<std::tr1::shared_ptr<const PackageID> >("origin_id"),
v.member<bool>("best"),
@@ -91,6 +107,18 @@ ChangesToMakeDecision::deserialise(Deserialisation & d)
v.member<bool>("taken"),
v.member<std::tr1::shared_ptr<const Destination> >("destination")
));
+
+ {
+ const std::tr1::shared_ptr<Deserialisation> dn(v.find_remove_member("required_confirmations_if_any"));
+ if (! dn->null())
+ {
+ Deserialisator vv(*dn, "c");
+ for (int n(1), n_end(vv.member<int>("count") + 1) ; n != n_end ; ++n)
+ result->add_required_confirmation(vv.member<std::tr1::shared_ptr<RequiredConfirmation> >(stringify(n)));
+ }
+ }
+
+ return result;
}
const std::tr1::shared_ptr<UnableToMakeDecision>
@@ -116,15 +144,29 @@ RemoveDecision::deserialise(Deserialisation & d)
Deserialisator v(d, "RemoveDecision");
std::tr1::shared_ptr<PackageIDSequence> ids(new PackageIDSequence);
- Deserialisator vv(*v.find_remove_member("ids"), "c");
- for (int n(1), n_end(vv.member<int>("count") + 1) ; n != n_end ; ++n)
- ids->push_back(vv.member<std::tr1::shared_ptr<const PackageID> >(stringify(n)));
+ {
+ Deserialisator vv(*v.find_remove_member("ids"), "c");
+ for (int n(1), n_end(vv.member<int>("count") + 1) ; n != n_end ; ++n)
+ ids->push_back(vv.member<std::tr1::shared_ptr<const PackageID> >(stringify(n)));
+ }
- return make_shared_ptr(new RemoveDecision(
+ const std::tr1::shared_ptr<RemoveDecision> result(new RemoveDecision(
v.member<Resolvent>("resolvent"),
ids,
v.member<bool>("taken")
));
+
+ {
+ const std::tr1::shared_ptr<Deserialisation> dn(v.find_remove_member("required_confirmations_if_any"));
+ if (! dn->null())
+ {
+ Deserialisator vv(*dn, "c");
+ for (int n(1), n_end(vv.member<int>("count") + 1) ; n != n_end ; ++n)
+ result->add_required_confirmation(vv.member<std::tr1::shared_ptr<RequiredConfirmation> >(stringify(n)));
+ }
+ }
+
+ return result;
}
namespace paludis
@@ -278,6 +320,7 @@ namespace paludis
ChangeType change_type;
const bool taken;
std::tr1::shared_ptr<const Destination> destination;
+ std::tr1::shared_ptr<RequiredConfirmations> required_confirmations;
Implementation(
const Resolvent & l,
@@ -328,6 +371,20 @@ ChangesToMakeDecision::set_destination(const std::tr1::shared_ptr<const Destinat
_imp->destination = d;
}
+const std::tr1::shared_ptr<const RequiredConfirmations>
+ChangesToMakeDecision::required_confirmations_if_any() const
+{
+ return _imp->required_confirmations;
+}
+
+void
+ChangesToMakeDecision::add_required_confirmation(const std::tr1::shared_ptr<const RequiredConfirmation> & r)
+{
+ if (! _imp->required_confirmations)
+ _imp->required_confirmations.reset(new RequiredConfirmations);
+ _imp->required_confirmations->push_back(r);
+}
+
const std::tr1::shared_ptr<const PackageID>
ChangesToMakeDecision::origin_id() const
{
@@ -374,6 +431,7 @@ ChangesToMakeDecision::serialise(Serialiser & s) const
.member(SerialiserFlags<>(), "change_type", stringify(change_type()))
.member(SerialiserFlags<serialise::might_be_null>(), "destination", destination())
.member(SerialiserFlags<>(), "taken", taken())
+ .member(SerialiserFlags<serialise::might_be_null, serialise::container>(), "required_confirmations_if_any", required_confirmations_if_any())
;
}
@@ -448,6 +506,7 @@ namespace paludis
const Resolvent resolvent;
const std::tr1::shared_ptr<const PackageIDSequence> ids;
const bool taken;
+ std::tr1::shared_ptr<RequiredConfirmations> required_confirmations;
Implementation(const Resolvent & l, const std::tr1::shared_ptr<const PackageIDSequence> & i, const bool t) :
resolvent(l),
@@ -489,6 +548,20 @@ RemoveDecision::ids() const
return _imp->ids;
}
+const std::tr1::shared_ptr<const RequiredConfirmations>
+RemoveDecision::required_confirmations_if_any() const
+{
+ return _imp->required_confirmations;
+}
+
+void
+RemoveDecision::add_required_confirmation(const std::tr1::shared_ptr<const RequiredConfirmation> & r)
+{
+ if (! _imp->required_confirmations)
+ _imp->required_confirmations.reset(new RequiredConfirmations);
+ _imp->required_confirmations->push_back(r);
+}
+
void
RemoveDecision::serialise(Serialiser & s) const
{
@@ -496,6 +569,7 @@ RemoveDecision::serialise(Serialiser & s) const
.member(SerialiserFlags<>(), "resolvent", resolvent())
.member(SerialiserFlags<>(), "taken", taken())
.member(SerialiserFlags<serialise::might_be_null, serialise::container>(), "ids", ids())
+ .member(SerialiserFlags<serialise::might_be_null, serialise::container>(), "required_confirmations_if_any", required_confirmations_if_any())
;
}
diff --git a/paludis/resolver/decision.hh b/paludis/resolver/decision.hh
index 2ae9e13..f17d37d 100644
--- a/paludis/resolver/decision.hh
+++ b/paludis/resolver/decision.hh
@@ -25,6 +25,7 @@
#include <paludis/resolver/unsuitable_candidates-fwd.hh>
#include <paludis/resolver/change_type-fwd.hh>
#include <paludis/resolver/resolvent-fwd.hh>
+#include <paludis/resolver/required_confirmations-fwd.hh>
#include <paludis/util/private_implementation_pattern.hh>
#include <paludis/util/simple_visitor.hh>
#include <paludis/util/type_list.hh>
@@ -100,6 +101,11 @@ namespace paludis
class PALUDIS_VISIBLE ChangeOrRemoveDecision :
public Decision
{
+ public:
+ static const std::tr1::shared_ptr<ChangeOrRemoveDecision> deserialise(
+ Deserialisation & d) PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ virtual const std::tr1::shared_ptr<const RequiredConfirmations> required_confirmations_if_any() const PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
};
class PALUDIS_VISIBLE ChangesToMakeDecision :
@@ -137,6 +143,9 @@ namespace paludis
virtual const Resolvent resolvent() const PALUDIS_ATTRIBUTE((warn_unused_result));
virtual bool taken() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ virtual const std::tr1::shared_ptr<const RequiredConfirmations> required_confirmations_if_any() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ void add_required_confirmation(const std::tr1::shared_ptr<const RequiredConfirmation> &);
+
virtual void serialise(Serialiser &) const;
static const std::tr1::shared_ptr<ChangesToMakeDecision> deserialise(
@@ -162,6 +171,9 @@ namespace paludis
const std::tr1::shared_ptr<const PackageIDSequence> ids() const
PALUDIS_ATTRIBUTE((warn_unused_result));
+ virtual const std::tr1::shared_ptr<const RequiredConfirmations> required_confirmations_if_any() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ void add_required_confirmation(const std::tr1::shared_ptr<const RequiredConfirmation> &);
+
virtual void serialise(Serialiser &) const;
static const std::tr1::shared_ptr<RemoveDecision> deserialise(
diff --git a/paludis/resolver/failure_kinds-fwd.hh b/paludis/resolver/decisions-fwd.hh
index 86384a1..ec52a35 100644
--- a/paludis/resolver/failure_kinds-fwd.hh
+++ b/paludis/resolver/decisions-fwd.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009 Ciaran McCreesh
+ * 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
@@ -17,22 +17,22 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef PALUDIS_GUARD_PALUDIS_RESOLVER_FAILURE_KINDS_FWD_HH
-#define PALUDIS_GUARD_PALUDIS_RESOLVER_FAILURE_KINDS_FWD_HH 1
+#ifndef PALUDIS_GUARD_PALUDIS_RESOLVER_DECISIONS_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_RESOLVER_DECISIONS_FWD_HH 1
-#include <paludis/util/attributes.hh>
-#include <paludis/util/options.hh>
-#include <iosfwd>
+#include <paludis/util/no_type.hh>
+#include <paludis/resolver/orderer_notes-fwd.hh>
+#include <paludis/resolver/decision-fwd.hh>
+#include <tr1/memory>
namespace paludis
{
namespace resolver
{
+ template <typename Decision_, typename Notes_ = NoType<0u> *>
+ struct Decisions;
-#include <paludis/resolver/failure_kinds-se.hh>
-
- typedef Options<FailureKind> FailureKinds;
-
+ typedef Decisions<ChangeOrRemoveDecision, std::tr1::shared_ptr<const OrdererNotes> > OrderedChangeOrRemoveDecisions;
}
}
diff --git a/paludis/resolver/decisions.cc b/paludis/resolver/decisions.cc
new file mode 100644
index 0000000..c247ce9
--- /dev/null
+++ b/paludis/resolver/decisions.cc
@@ -0,0 +1,211 @@
+/* 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 <paludis/resolver/decisions.hh>
+#include <paludis/resolver/decision.hh>
+#include <paludis/resolver/orderer_notes.hh>
+#include <paludis/util/private_implementation_pattern-impl.hh>
+#include <paludis/util/simple_visitor_cast.hh>
+#include <paludis/util/exception.hh>
+#include <paludis/util/stringify.hh>
+#include <paludis/util/wrapped_forward_iterator-impl.hh>
+#include <paludis/serialise-impl.hh>
+#include <list>
+
+using namespace paludis;
+using namespace paludis::resolver;
+
+namespace
+{
+ template <typename Decision_, typename Notes_>
+ struct ContainerTraits
+ {
+ typedef std::list<std::pair<
+ std::tr1::shared_ptr<const Decision_>,
+ Notes_> > ContainerType;
+
+ static void do_push_back(
+ ContainerType & c,
+ const std::tr1::shared_ptr<const Decision_> & d,
+ const Notes_ & n)
+ {
+ c.push_back(std::make_pair(d, n));
+ }
+
+ static void do_member(SerialiserObjectWriter & w, int n,
+ const std::pair<std::tr1::shared_ptr<const Decision_>, Notes_> & d)
+ {
+ w.member(SerialiserFlags<serialise::might_be_null>(), stringify(n) + ".1", d.first);
+ w.member(SerialiserFlags<serialise::might_be_null>(), stringify(n) + ".2", d.second);
+ }
+
+ static void do_extract(
+ std::tr1::shared_ptr<Decisions<Decision_, Notes_> > & result,
+ Deserialisator & v,
+ int n)
+ {
+ result->push_back(
+ v.member<std::tr1::shared_ptr<Decision_> >(stringify(n) + ".1"),
+ v.member<Notes_>(stringify(n) + ".2")
+ );
+ }
+ };
+
+ template <typename Decision_>
+ struct ContainerTraits<Decision_, NoType<0u> *>
+ {
+ typedef std::list<std::tr1::shared_ptr<const Decision_> > ContainerType;
+
+ static void do_push_back(
+ ContainerType & c,
+ const std::tr1::shared_ptr<const Decision_> & d,
+ const NoType<0u> * const)
+ {
+ c.push_back(d);
+ }
+
+ static void do_member(SerialiserObjectWriter & w, int n, const std::tr1::shared_ptr<const Decision_> & d)
+ {
+ w.member(SerialiserFlags<serialise::might_be_null>(), stringify(n), d);
+ }
+
+ static void do_extract(
+ std::tr1::shared_ptr<Decisions<Decision_> > & result,
+ Deserialisator & v,
+ int n)
+ {
+ result->push_back(v.member<std::tr1::shared_ptr<Decision_> >(stringify(n)));
+ }
+ };
+}
+
+namespace paludis
+{
+#ifdef PALUDIS_NO_DOUBLE_TEMPLATE
+ template <>
+#endif
+ template <typename Decision_, typename Notes_>
+ struct Implementation<Decisions<Decision_, Notes_> >
+ {
+ typename ContainerTraits<Decision_, Notes_>::ContainerType values;
+ };
+
+#ifdef PALUDIS_NO_DOUBLE_TEMPLATE
+ template <>
+#endif
+ template <typename Decision_, typename Notes_>
+ struct WrappedForwardIteratorTraits<DecisionsConstIteratorTag<Decision_, Notes_> >
+ {
+ typedef typename ContainerTraits<Decision_, Notes_>::ContainerType::const_iterator UnderlyingIterator;
+ };
+}
+
+template <typename Decision_, typename Notes_>
+Decisions<Decision_, Notes_>::Decisions() :
+ PrivateImplementationPattern<Decisions<Decision_, Notes_> >(new Implementation<Decisions<Decision_, Notes_> >)
+{
+}
+
+template <typename Decision_, typename Notes_>
+Decisions<Decision_, Notes_>::~Decisions()
+{
+}
+
+template <typename Decision_, typename Notes_>
+void
+Decisions<Decision_, Notes_>::push_back(
+ const std::tr1::shared_ptr<const Decision_> & d,
+ const Notes_ & n)
+{
+ ContainerTraits<Decision_, Notes_>::do_push_back(_imp->values, d, n);
+}
+
+template <typename Decision_, typename Notes_>
+void
+Decisions<Decision_, Notes_>::cast_push_back(
+ const std::tr1::shared_ptr<const Decision> & d,
+ const Notes_ & n)
+{
+ if (! simple_visitor_cast<const Decision_>(*d))
+ throw InternalError(PALUDIS_HERE, "Wrong Decision type");
+ push_back(std::tr1::static_pointer_cast<const Decision_>(d), n);
+}
+
+template <typename Decision_, typename Notes_>
+typename Decisions<Decision_, Notes_>::ConstIterator
+Decisions<Decision_, Notes_>::begin() const
+{
+ return ConstIterator(_imp->values.begin());
+}
+
+template <typename Decision_, typename Notes_>
+typename Decisions<Decision_, Notes_>::ConstIterator
+Decisions<Decision_, Notes_>::end() const
+{
+ return ConstIterator(_imp->values.end());
+}
+
+template <typename Decision_, typename Notes_>
+bool
+Decisions<Decision_, Notes_>::empty() const
+{
+ return _imp->values.empty();
+}
+
+template <typename Decision_, typename Notes_>
+void
+Decisions<Decision_, Notes_>::serialise(Serialiser & s) const
+{
+ SerialiserObjectWriter w(s.object("Decisions"));
+
+ int n(0);
+ for (ConstIterator i(begin()), i_end(end()) ;
+ i != i_end ; ++i)
+ ContainerTraits<Decision_, Notes_>::do_member(w, ++n, *i);
+
+ w.member(SerialiserFlags<>(), "count", stringify(n));
+}
+
+template <typename Decision_, typename Notes_>
+const std::tr1::shared_ptr<Decisions<Decision_, Notes_> >
+Decisions<Decision_, Notes_>::deserialise(Deserialisation & d)
+{
+ Deserialisator v(d, "Decisions");
+ std::tr1::shared_ptr<Decisions<Decision_, Notes_> > result(new Decisions<Decision_, Notes_>);
+ for (int n(1), n_end(v.member<int>("count") + 1) ; n != n_end ; ++n)
+ ContainerTraits<Decision_, Notes_>::do_extract(result, v, n);
+ return result;
+}
+
+template class Decisions<UnableToMakeDecision>;
+template class Decisions<ChangesToMakeDecision>;
+template class Decisions<ChangeOrRemoveDecision>;
+template class Decisions<ChangeOrRemoveDecision, std::tr1::shared_ptr<const OrdererNotes> >;
+
+template class WrappedForwardIterator<Decisions<UnableToMakeDecision>::ConstIteratorTag,
+ const std::tr1::shared_ptr<const UnableToMakeDecision> >;
+template class WrappedForwardIterator<Decisions<ChangesToMakeDecision>::ConstIteratorTag,
+ const std::tr1::shared_ptr<const ChangesToMakeDecision> >;
+template class WrappedForwardIterator<Decisions<ChangeOrRemoveDecision>::ConstIteratorTag,
+ const std::tr1::shared_ptr<const ChangeOrRemoveDecision> >;
+template class WrappedForwardIterator<Decisions<ChangeOrRemoveDecision, std::tr1::shared_ptr<const OrdererNotes> >::ConstIteratorTag,
+ const std::pair<
+ std::tr1::shared_ptr<const ChangeOrRemoveDecision>,
+ std::tr1::shared_ptr<const OrdererNotes> > >;
+
diff --git a/paludis/resolver/decisions.hh b/paludis/resolver/decisions.hh
new file mode 100644
index 0000000..432bcbe
--- /dev/null
+++ b/paludis/resolver/decisions.hh
@@ -0,0 +1,104 @@
+/* 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_PALUDIS_RESOLVER_DECISIONS_HH
+#define PALUDIS_GUARD_PALUDIS_RESOLVER_DECISIONS_HH 1
+
+#include <paludis/resolver/decisions-fwd.hh>
+#include <paludis/resolver/decision-fwd.hh>
+#include <paludis/resolver/orderer_notes-fwd.hh>
+#include <paludis/util/private_implementation_pattern.hh>
+#include <paludis/util/wrapped_forward_iterator.hh>
+#include <paludis/util/no_type.hh>
+#include <paludis/serialise-fwd.hh>
+#include <tr1/memory>
+
+namespace paludis
+{
+ namespace resolver
+ {
+ template <typename Decision_, typename Notes_>
+ struct DecisionsConstIteratorTag;
+
+ template <typename Decision_, typename Notes_>
+ struct DecisionsIteratorValueType
+ {
+ typedef const std::pair<std::tr1::shared_ptr<const Decision_>, Notes_> Type;
+ };
+
+ template <typename Decision_>
+ struct DecisionsIteratorValueType<Decision_, NoType<0u> *>
+ {
+ typedef const std::tr1::shared_ptr<const Decision_> Type;
+ };
+
+ template <typename Decision_, typename Notes_>
+ class PALUDIS_VISIBLE Decisions :
+ private PrivateImplementationPattern<Decisions<Decision_, Notes_> >
+ {
+ using PrivateImplementationPattern<Decisions<Decision_, Notes_> >::_imp;
+
+ public:
+ Decisions();
+ ~Decisions();
+
+ void push_back(
+ const std::tr1::shared_ptr<const Decision_> &,
+ const Notes_ & = static_cast<NoType<0u> *>(0));
+
+ void cast_push_back(
+ const std::tr1::shared_ptr<const Decision> &,
+ const Notes_ & = static_cast<NoType<0u> *>(0));
+
+ typedef DecisionsConstIteratorTag<Decision_, Notes_> ConstIteratorTag;
+ typedef WrappedForwardIterator<ConstIteratorTag,
+ typename DecisionsIteratorValueType<Decision_, Notes_>::Type> ConstIterator;
+ ConstIterator begin() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ ConstIterator end() const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ bool empty() const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ void serialise(Serialiser &) const;
+ static const std::tr1::shared_ptr<Decisions> deserialise(Deserialisation & d) PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
+
+#ifdef PALUDIS_HAVE_EXTERN_TEMPLATE
+ extern template class Decisions<UnableToMakeDecision>;
+ extern template class Decisions<ChangesToMakeDecision>;
+ extern template class Decisions<ChangeOrRemoveDecision>;
+ extern template class Decisions<ChangeOrRemoveDecision, std::tr1::shared_ptr<const OrdererNotes> >;
+#endif
+ }
+
+#ifdef PALUDIS_HAVE_EXTERN_TEMPLATE
+ extern template class WrappedForwardIterator<resolver::Decisions<resolver::UnableToMakeDecision>::ConstIteratorTag,
+ const std::tr1::shared_ptr<const resolver::UnableToMakeDecision> >;
+ extern template class WrappedForwardIterator<resolver::Decisions<resolver::ChangesToMakeDecision>::ConstIteratorTag,
+ const std::tr1::shared_ptr<const resolver::ChangesToMakeDecision> >;
+ extern template class WrappedForwardIterator<resolver::Decisions<resolver::ChangeOrRemoveDecision>::ConstIteratorTag,
+ const std::tr1::shared_ptr<const resolver::ChangeOrRemoveDecision> >;
+ extern template class WrappedForwardIterator<resolver::Decisions<resolver::ChangeOrRemoveDecision,
+ std::tr1::shared_ptr<const resolver::OrdererNotes> >::ConstIteratorTag,
+ const std::pair<
+ std::tr1::shared_ptr<const resolver::ChangeOrRemoveDecision>,
+ std::tr1::shared_ptr<const resolver::OrdererNotes> > >;
+#endif
+}
+
+#endif
diff --git a/paludis/resolver/failure_kinds.se b/paludis/resolver/failure_kinds.se
deleted file mode 100644
index 236812a..0000000
--- a/paludis/resolver/failure_kinds.se
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/usr/bin/env bash
-# vim: set sw=4 sts=4 et ft=sh :
-
-make_enum_FailureKind()
-{
- prefix fk
- namespace paludis::resolver
-
- key fk_ignorable_always "We can always ignore this failure"
- key fk_ignorable_if_satisfied "We can ignore this failure if we're if-satisfied"
-
- want_destringify
-}
-
diff --git a/paludis/resolver/job-fwd.hh b/paludis/resolver/job-fwd.hh
index 5322bd5..c342b11 100644
--- a/paludis/resolver/job-fwd.hh
+++ b/paludis/resolver/job-fwd.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009, 2010 Ciaran McCreesh
+ * 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
@@ -24,14 +24,14 @@ namespace paludis
{
namespace resolver
{
- struct Job;
+ class PretendJob;
- struct SimpleInstallJob;
- struct UninstallJob;
- struct FetchJob;
- struct UsableJob;
- struct UsableGroupJob;
- struct ErrorJob;
+ class ExecuteJob;
+ class FetchJob;
+ class InstallJob;
+ class UninstallJob;
+
+ class JobID;
}
}
diff --git a/paludis/resolver/job.cc b/paludis/resolver/job.cc
index e5facec..75bf8c7 100644
--- a/paludis/resolver/job.cc
+++ b/paludis/resolver/job.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009, 2010 Ciaran McCreesh
+ * 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
@@ -18,17 +18,13 @@
*/
#include <paludis/resolver/job.hh>
-#include <paludis/resolver/arrow.hh>
-#include <paludis/resolver/resolution.hh>
-#include <paludis/resolver/decision.hh>
-#include <paludis/resolver/required_confirmations.hh>
+#include <paludis/resolver/job_requirements.hh>
#include <paludis/util/private_implementation_pattern-impl.hh>
+#include <paludis/util/make_shared_ptr.hh>
#include <paludis/util/sequence.hh>
-#include <paludis/util/make_named_values.hh>
-#include <paludis/util/wrapped_forward_iterator.hh>
-#include <paludis/util/stringify.hh>
-#include <paludis/util/join.hh>
#include <paludis/serialise-impl.hh>
+#include <paludis/package_id.hh>
+#include <paludis/name.hh>
using namespace paludis;
using namespace paludis::resolver;
@@ -36,548 +32,300 @@ using namespace paludis::resolver;
namespace paludis
{
template <>
- struct Implementation<UsableJob>
+ struct Implementation<PretendJob>
{
- const std::tr1::shared_ptr<const Resolution> resolution;
- const std::tr1::shared_ptr<ArrowSequence> arrows;
- const std::tr1::shared_ptr<JobIDSequence> used_existing_packages_when_ordering;
- const std::tr1::shared_ptr<RequiredConfirmations> required_confirmations;
-
- Implementation(const std::tr1::shared_ptr<const Resolution> & r) :
- resolution(r),
- arrows(new ArrowSequence),
- used_existing_packages_when_ordering(new JobIDSequence),
- required_confirmations(new RequiredConfirmations)
- {
- }
- };
-
- template <>
- struct Implementation<UsableGroupJob>
- {
- const std::tr1::shared_ptr<const JobIDSequence> ids;
- const std::tr1::shared_ptr<ArrowSequence> arrows;
- const std::tr1::shared_ptr<JobIDSequence> used_existing_packages_when_ordering;
- const std::tr1::shared_ptr<RequiredConfirmations> required_confirmations;
-
- Implementation(const std::tr1::shared_ptr<const JobIDSequence> & i) :
- ids(i),
- arrows(new ArrowSequence),
- used_existing_packages_when_ordering(new JobIDSequence),
- required_confirmations(new RequiredConfirmations)
- {
- }
- };
-
- template <>
- struct Implementation<FetchJob>
- {
- const std::tr1::shared_ptr<const Resolution> resolution;
- const std::tr1::shared_ptr<const ChangesToMakeDecision> decision;
- const std::tr1::shared_ptr<ArrowSequence> arrows;
- const std::tr1::shared_ptr<JobIDSequence> used_existing_packages_when_ordering;
- const std::tr1::shared_ptr<RequiredConfirmations> required_confirmations;
-
- Implementation(const std::tr1::shared_ptr<const Resolution> & r,
- const std::tr1::shared_ptr<const ChangesToMakeDecision> & d) :
- resolution(r),
- decision(d),
- arrows(new ArrowSequence),
- used_existing_packages_when_ordering(new JobIDSequence),
- required_confirmations(new RequiredConfirmations)
- {
- }
- };
-
- template <>
- struct Implementation<SimpleInstallJob>
- {
- const std::tr1::shared_ptr<const Resolution> resolution;
- const std::tr1::shared_ptr<const ChangesToMakeDecision> decision;
- const std::tr1::shared_ptr<ArrowSequence> arrows;
- const std::tr1::shared_ptr<JobIDSequence> used_existing_packages_when_ordering;
- const std::tr1::shared_ptr<RequiredConfirmations> required_confirmations;
-
- Implementation(const std::tr1::shared_ptr<const Resolution> & r,
- const std::tr1::shared_ptr<const ChangesToMakeDecision> & d) :
- resolution(r),
- decision(d),
- arrows(new ArrowSequence),
- used_existing_packages_when_ordering(new JobIDSequence),
- required_confirmations(new RequiredConfirmations)
- {
- }
- };
-
- template <>
- struct Implementation<UninstallJob>
- {
- const std::tr1::shared_ptr<const Resolution> resolution;
- const std::tr1::shared_ptr<const RemoveDecision> decision;
- const std::tr1::shared_ptr<ArrowSequence> arrows;
- const std::tr1::shared_ptr<JobIDSequence> used_existing_packages_when_ordering;
- const std::tr1::shared_ptr<RequiredConfirmations> required_confirmations;
-
- Implementation(const std::tr1::shared_ptr<const Resolution> & r,
- const std::tr1::shared_ptr<const RemoveDecision> & d) :
- resolution(r),
- decision(d),
- arrows(new ArrowSequence),
- used_existing_packages_when_ordering(new JobIDSequence),
- required_confirmations(new RequiredConfirmations)
- {
- }
- };
+ const std::tr1::shared_ptr<const PackageID> origin_id;
- template <>
- struct Implementation<ErrorJob>
- {
- const std::tr1::shared_ptr<const Resolution> resolution;
- const std::tr1::shared_ptr<const UnableToMakeDecision> decision;
- const std::tr1::shared_ptr<ArrowSequence> arrows;
- const std::tr1::shared_ptr<JobIDSequence> used_existing_packages_when_ordering;
- const std::tr1::shared_ptr<RequiredConfirmations> required_confirmations;
-
- Implementation(const std::tr1::shared_ptr<const Resolution> & r,
- const std::tr1::shared_ptr<const UnableToMakeDecision> & d) :
- resolution(r),
- decision(d),
- arrows(new ArrowSequence),
- used_existing_packages_when_ordering(new JobIDSequence),
- required_confirmations(new RequiredConfirmations)
+ Implementation(const std::tr1::shared_ptr<const PackageID> & o) :
+ origin_id(o)
{
}
};
}
-Job::~Job()
+PretendJob::PretendJob(const std::tr1::shared_ptr<const PackageID> & o) :
+ PrivateImplementationPattern<PretendJob>(new Implementation<PretendJob>(o))
{
}
-namespace
+PretendJob::~PretendJob()
{
- void do_arrows(
- const std::tr1::shared_ptr<Job> & result,
- Deserialisator & v)
- {
- Deserialisator vv(*v.find_remove_member("arrows"), "c");
- for (int n(1), n_end(vv.member<int>("count") + 1) ; n != n_end ; ++n)
- result->arrows()->push_back(vv.member<Arrow>(stringify(n)));
- }
-
- void do_existing(
- const std::tr1::shared_ptr<Job> & result,
- Deserialisator & v)
- {
- Deserialisator vv(*v.find_remove_member("used_existing_packages_when_ordering"), "c");
- for (int n(1), n_end(vv.member<int>("count") + 1) ; n != n_end ; ++n)
- result->used_existing_packages_when_ordering()->push_back(vv.member<JobID>(stringify(n)));
- }
-
- void do_required(
- const std::tr1::shared_ptr<Job> & result,
- Deserialisator & v)
- {
- Deserialisator vv(*v.find_remove_member("required_confirmations"), "c");
- for (int n(1), n_end(vv.member<int>("count") + 1) ; n != n_end ; ++n)
- result->required_confirmations()->push_back(vv.member<std::tr1::shared_ptr<RequiredConfirmation> >(stringify(n)));
- }
-}
-
-const std::tr1::shared_ptr<Job>
-Job::deserialise(Deserialisation & d)
-{
- std::tr1::shared_ptr<Job> result;
-
- if (d.class_name() == "UsableJob")
- {
- Deserialisator v(d, "UsableJob");
- result.reset(new UsableJob(
- v.member<std::tr1::shared_ptr<Resolution> >("resolution")
- ));
- do_arrows(result, v);
- do_existing(result, v);
- do_required(result, v);
- }
- else if (d.class_name() == "UsableGroupJob")
- {
- Deserialisator v(d, "UsableGroupJob");
-
- Deserialisator vv(*v.find_remove_member("job_ids"), "c");
- const std::tr1::shared_ptr<JobIDSequence> ids(new JobIDSequence);
- for (int n(1), n_end(vv.member<int>("count") + 1) ; n != n_end ; ++n)
- ids->push_back(vv.member<JobID>(stringify(n)));
-
- result.reset(new UsableGroupJob(ids));
- do_arrows(result, v);
- do_existing(result, v);
- do_required(result, v);
- }
- else if (d.class_name() == "SimpleInstallJob")
- {
- Deserialisator v(d, "SimpleInstallJob");
- result.reset(new SimpleInstallJob(
- v.member<std::tr1::shared_ptr<Resolution> >("resolution"),
- v.member<std::tr1::shared_ptr<ChangesToMakeDecision> >("changes_to_make_decision")
- ));
- do_arrows(result, v);
- do_existing(result, v);
- do_required(result, v);
- }
- else if (d.class_name() == "UninstallJob")
- {
- Deserialisator v(d, "UninstallJob");
- result.reset(new UninstallJob(
- v.member<std::tr1::shared_ptr<Resolution> >("resolution"),
- v.member<std::tr1::shared_ptr<RemoveDecision> >("remove_decision")
- ));
- do_arrows(result, v);
- do_existing(result, v);
- do_required(result, v);
- }
- else if (d.class_name() == "FetchJob")
- {
- Deserialisator v(d, "FetchJob");
- result.reset(new FetchJob(
- v.member<std::tr1::shared_ptr<Resolution> >("resolution"),
- v.member<std::tr1::shared_ptr<ChangesToMakeDecision> >("changes_to_make_decision")
- ));
- do_arrows(result, v);
- do_existing(result, v);
- do_required(result, v);
- }
- else if (d.class_name() == "ErrorJob")
- {
- Deserialisator v(d, "ErrorJob");
- result.reset(new ErrorJob(
- v.member<std::tr1::shared_ptr<Resolution> >("resolution"),
- v.member<std::tr1::shared_ptr<UnableToMakeDecision> >("unable_to_make_decision")
- ));
- do_arrows(result, v);
- do_existing(result, v);
- do_required(result, v);
- }
- else
- throw InternalError(PALUDIS_HERE, "unknown class '" + stringify(d.class_name()) + "'");
-
- return result;
}
-UsableJob::UsableJob(const std::tr1::shared_ptr<const Resolution> & r) :
- PrivateImplementationPattern<UsableJob>(new Implementation<UsableJob>(r))
+const std::tr1::shared_ptr<const PackageID>
+PretendJob::origin_id() const
{
+ return _imp->origin_id;
}
-UsableJob::~UsableJob()
+const std::tr1::shared_ptr<PretendJob>
+PretendJob::deserialise(Deserialisation & d)
{
+ Deserialisator v(d, "PretendJob");
+ return make_shared_ptr(new PretendJob(
+ v.member<std::tr1::shared_ptr<const PackageID> >("origin_id")
+ ));
}
-const std::tr1::shared_ptr<const Resolution>
-UsableJob::resolution() const
+void
+PretendJob::serialise(Serialiser & s) const
{
- return _imp->resolution;
+ s.object("PretendJob")
+ .member(SerialiserFlags<serialise::might_be_null>(), "origin_id", origin_id())
+ ;
}
-const std::tr1::shared_ptr<const ArrowSequence>
-UsableJob::arrows() const
+ExecuteJob::~ExecuteJob()
{
- return _imp->arrows;
}
-const std::tr1::shared_ptr<ArrowSequence>
-UsableJob::arrows()
+const std::tr1::shared_ptr<ExecuteJob>
+ExecuteJob::deserialise(Deserialisation & d)
{
- return _imp->arrows;
+ if (d.class_name() == "FetchJob")
+ return FetchJob::deserialise(d);
+ else if (d.class_name() == "InstallJob")
+ return InstallJob::deserialise(d);
+ else if (d.class_name() == "UninstallJob")
+ return UninstallJob::deserialise(d);
+ else
+ throw InternalError(PALUDIS_HERE, "unknown class '" + stringify(d.class_name()) + "'");
}
-const std::tr1::shared_ptr<const JobIDSequence>
-UsableJob::used_existing_packages_when_ordering() const
+namespace paludis
{
- return _imp->used_existing_packages_when_ordering;
+ template <>
+ struct Implementation<FetchJob>
+ {
+ const std::tr1::shared_ptr<const JobRequirements> requirements;
+ const std::tr1::shared_ptr<const PackageID> origin_id;
+ std::tr1::shared_ptr<JobState> state;
+
+ Implementation(
+ const std::tr1::shared_ptr<const JobRequirements> & r,
+ const std::tr1::shared_ptr<const PackageID> & o) :
+ requirements(r),
+ origin_id(o)
+ {
+ }
+ };
}
-const std::tr1::shared_ptr<JobIDSequence>
-UsableJob::used_existing_packages_when_ordering()
+FetchJob::FetchJob(
+ const std::tr1::shared_ptr<const JobRequirements> & r,
+ const std::tr1::shared_ptr<const PackageID> & o) :
+ PrivateImplementationPattern<FetchJob>(new Implementation<FetchJob>(r, o))
{
- return _imp->used_existing_packages_when_ordering;
}
-const std::tr1::shared_ptr<const RequiredConfirmations>
-UsableJob::required_confirmations() const
+FetchJob::~FetchJob()
{
- return _imp->required_confirmations;
}
-const std::tr1::shared_ptr<RequiredConfirmations>
-UsableJob::required_confirmations()
+const std::tr1::shared_ptr<const PackageID>
+FetchJob::origin_id() const
{
- return _imp->required_confirmations;
+ return _imp->origin_id;
}
-const JobID
-UsableJob::id() const
+const std::tr1::shared_ptr<JobState>
+FetchJob::state() const
{
- return make_named_values<JobID>(
- n::string_id() = "usable:" + stringify(resolution()->resolvent())
- );
+ return _imp->state;
}
void
-UsableJob::serialise(Serialiser & s) const
-{
- s.object("UsableJob")
- .member(SerialiserFlags<serialise::might_be_null, serialise::container>(), "arrows", arrows())
- .member(SerialiserFlags<serialise::might_be_null>(), "resolution", resolution())
- .member(SerialiserFlags<serialise::container, serialise::might_be_null>(),
- "required_confirmations", required_confirmations())
- .member(SerialiserFlags<serialise::container, serialise::might_be_null>(),
- "used_existing_packages_when_ordering", used_existing_packages_when_ordering())
- ;
-}
-
-UsableGroupJob::UsableGroupJob(const std::tr1::shared_ptr<const JobIDSequence> & r) :
- PrivateImplementationPattern<UsableGroupJob>(new Implementation<UsableGroupJob>(r))
+FetchJob::set_state(const std::tr1::shared_ptr<JobState> & s)
{
+ _imp->state = s;
}
-UsableGroupJob::~UsableGroupJob()
+const std::tr1::shared_ptr<const JobRequirements>
+FetchJob::requirements() const
{
+ return _imp->requirements;
}
-const std::tr1::shared_ptr<const JobIDSequence>
-UsableGroupJob::job_ids() const
+const std::tr1::shared_ptr<FetchJob>
+FetchJob::deserialise(Deserialisation & d)
{
- return _imp->ids;
-}
-
-const std::tr1::shared_ptr<const ArrowSequence>
-UsableGroupJob::arrows() const
-{
- return _imp->arrows;
-}
-
-const std::tr1::shared_ptr<ArrowSequence>
-UsableGroupJob::arrows()
-{
- return _imp->arrows;
-}
+ Deserialisator v(d, "FetchJob");
-const std::tr1::shared_ptr<const JobIDSequence>
-UsableGroupJob::used_existing_packages_when_ordering() const
-{
- return _imp->used_existing_packages_when_ordering;
-}
-
-const std::tr1::shared_ptr<JobIDSequence>
-UsableGroupJob::used_existing_packages_when_ordering()
-{
- return _imp->used_existing_packages_when_ordering;
-}
-
-const std::tr1::shared_ptr<const RequiredConfirmations>
-UsableGroupJob::required_confirmations() const
-{
- return _imp->required_confirmations;
-}
-
-const std::tr1::shared_ptr<RequiredConfirmations>
-UsableGroupJob::required_confirmations()
-{
- return _imp->required_confirmations;
-}
-
-namespace
-{
- std::string stringify_job_id(const JobID & i)
+ std::tr1::shared_ptr<JobRequirements> requirements(new JobRequirements);
{
- return i.string_id();
+ Deserialisator vv(*v.find_remove_member("requirements"), "c");
+ for (int n(1), n_end(vv.member<int>("count") + 1) ; n != n_end ; ++n)
+ requirements->push_back(vv.member<JobRequirement>(stringify(n)));
}
-}
-const JobID
-UsableGroupJob::id() const
-{
- return make_named_values<JobID>(
- n::string_id() = "usable_group:" + join(_imp->ids->begin(), _imp->ids->end(), "+", &stringify_job_id)
- );
+ return make_shared_ptr(new FetchJob(
+ requirements,
+ v.member<std::tr1::shared_ptr<const PackageID> >("origin_id")
+ ));
}
void
-UsableGroupJob::serialise(Serialiser & s) const
-{
- s.object("UsableGroupJob")
- .member(SerialiserFlags<serialise::might_be_null, serialise::container>(), "arrows", arrows())
- .member(SerialiserFlags<serialise::might_be_null, serialise::container>(), "job_ids", job_ids())
- .member(SerialiserFlags<serialise::container, serialise::might_be_null>(),
- "required_confirmations", required_confirmations())
- .member(SerialiserFlags<serialise::container, serialise::might_be_null>(),
- "used_existing_packages_when_ordering", used_existing_packages_when_ordering())
- ;
-}
-
-FetchJob::FetchJob(const std::tr1::shared_ptr<const Resolution> & r,
- const std::tr1::shared_ptr<const ChangesToMakeDecision> & d) :
- PrivateImplementationPattern<FetchJob>(new Implementation<FetchJob>(r, d))
-{
-}
-
-FetchJob::~FetchJob()
-{
-}
-
-const std::tr1::shared_ptr<const Resolution>
-FetchJob::resolution() const
+FetchJob::serialise(Serialiser & s) const
{
- return _imp->resolution;
+ s.object("FetchJob")
+ .member(SerialiserFlags<serialise::container, serialise::might_be_null>(), "requirements", requirements())
+ .member(SerialiserFlags<serialise::might_be_null>(), "origin_id", origin_id())
+ ;
}
-const std::tr1::shared_ptr<const ChangesToMakeDecision>
-FetchJob::changes_to_make_decision() const
+namespace paludis
{
- return _imp->decision;
+ template <>
+ struct Implementation<InstallJob>
+ {
+ const std::tr1::shared_ptr<const JobRequirements> requirements;
+ const std::tr1::shared_ptr<const PackageID> origin_id;
+ const RepositoryName destination_repository_name;
+ const DestinationType destination_type;
+ const std::tr1::shared_ptr<const PackageIDSequence> replacing;
+
+ std::tr1::shared_ptr<JobState> state;
+
+ Implementation(
+ const std::tr1::shared_ptr<const JobRequirements> & q,
+ const std::tr1::shared_ptr<const PackageID> & o,
+ const RepositoryName & d,
+ const DestinationType t,
+ const std::tr1::shared_ptr<const PackageIDSequence> & r
+ ) :
+ requirements(q),
+ origin_id(o),
+ destination_repository_name(d),
+ destination_type(t),
+ replacing(r)
+ {
+ }
+ };
}
-const std::tr1::shared_ptr<const ArrowSequence>
-FetchJob::arrows() const
+InstallJob::InstallJob(
+ const std::tr1::shared_ptr<const JobRequirements> & q,
+ const std::tr1::shared_ptr<const PackageID> & o,
+ const RepositoryName & d,
+ const DestinationType t,
+ const std::tr1::shared_ptr<const PackageIDSequence> & r
+ ) :
+ PrivateImplementationPattern<InstallJob>(new Implementation<InstallJob>(q, o, d, t, r))
{
- return _imp->arrows;
}
-const std::tr1::shared_ptr<ArrowSequence>
-FetchJob::arrows()
+InstallJob::~InstallJob()
{
- return _imp->arrows;
}
-const std::tr1::shared_ptr<const JobIDSequence>
-FetchJob::used_existing_packages_when_ordering() const
+const std::tr1::shared_ptr<const PackageID>
+InstallJob::origin_id() const
{
- return _imp->used_existing_packages_when_ordering;
+ return _imp->origin_id;
}
-const std::tr1::shared_ptr<JobIDSequence>
-FetchJob::used_existing_packages_when_ordering()
+const RepositoryName
+InstallJob::destination_repository_name() const
{
- return _imp->used_existing_packages_when_ordering;
+ return _imp->destination_repository_name;
}
-const std::tr1::shared_ptr<const RequiredConfirmations>
-FetchJob::required_confirmations() const
+DestinationType
+InstallJob::destination_type() const
{
- return _imp->required_confirmations;
+ return _imp->destination_type;
}
-const std::tr1::shared_ptr<RequiredConfirmations>
-FetchJob::required_confirmations()
+const std::tr1::shared_ptr<const PackageIDSequence>
+InstallJob::replacing() const
{
- return _imp->required_confirmations;
+ return _imp->replacing;
}
-const JobID
-FetchJob::id() const
+const std::tr1::shared_ptr<JobState>
+InstallJob::state() const
{
- return make_named_values<JobID>(
- n::string_id() = "fetch:" + stringify(resolution()->resolvent())
- );
+ return _imp->state;
}
void
-FetchJob::serialise(Serialiser & s) const
-{
- s.object("FetchJob")
- .member(SerialiserFlags<serialise::might_be_null, serialise::container>(), "arrows", arrows())
- .member(SerialiserFlags<serialise::might_be_null>(), "changes_to_make_decision", changes_to_make_decision())
- .member(SerialiserFlags<serialise::might_be_null>(), "resolution", resolution())
- .member(SerialiserFlags<serialise::container, serialise::might_be_null>(),
- "required_confirmations", required_confirmations())
- .member(SerialiserFlags<serialise::container, serialise::might_be_null>(),
- "used_existing_packages_when_ordering", used_existing_packages_when_ordering())
- ;
-}
-
-SimpleInstallJob::SimpleInstallJob(const std::tr1::shared_ptr<const Resolution> & r,
- const std::tr1::shared_ptr<const ChangesToMakeDecision> & d) :
- PrivateImplementationPattern<SimpleInstallJob>(new Implementation<SimpleInstallJob>(r, d))
-{
-}
-
-SimpleInstallJob::~SimpleInstallJob()
-{
-}
-
-const std::tr1::shared_ptr<const Resolution>
-SimpleInstallJob::resolution() const
+InstallJob::set_state(const std::tr1::shared_ptr<JobState> & s)
{
- return _imp->resolution;
+ _imp->state = s;
}
-const std::tr1::shared_ptr<const ChangesToMakeDecision>
-SimpleInstallJob::changes_to_make_decision() const
+const std::tr1::shared_ptr<const JobRequirements>
+InstallJob::requirements() const
{
- return _imp->decision;
+ return _imp->requirements;
}
-const std::tr1::shared_ptr<const ArrowSequence>
-SimpleInstallJob::arrows() const
+const std::tr1::shared_ptr<InstallJob>
+InstallJob::deserialise(Deserialisation & d)
{
- return _imp->arrows;
-}
+ Deserialisator v(d, "InstallJob");
-const std::tr1::shared_ptr<ArrowSequence>
-SimpleInstallJob::arrows()
-{
- return _imp->arrows;
-}
+ std::tr1::shared_ptr<PackageIDSequence> replacing(new PackageIDSequence);
+ {
+ Deserialisator vv(*v.find_remove_member("replacing"), "c");
+ for (int n(1), n_end(vv.member<int>("count") + 1) ; n != n_end ; ++n)
+ replacing->push_back(vv.member<std::tr1::shared_ptr<const PackageID> >(stringify(n)));
+ }
-const std::tr1::shared_ptr<const JobIDSequence>
-SimpleInstallJob::used_existing_packages_when_ordering() const
-{
- return _imp->used_existing_packages_when_ordering;
-}
+ std::tr1::shared_ptr<JobRequirements> requirements(new JobRequirements);
+ {
+ Deserialisator vv(*v.find_remove_member("requirements"), "c");
+ for (int n(1), n_end(vv.member<int>("count") + 1) ; n != n_end ; ++n)
+ requirements->push_back(vv.member<JobRequirement>(stringify(n)));
+ }
-const std::tr1::shared_ptr<JobIDSequence>
-SimpleInstallJob::used_existing_packages_when_ordering()
-{
- return _imp->used_existing_packages_when_ordering;
+ return make_shared_ptr(new InstallJob(
+ requirements,
+ v.member<std::tr1::shared_ptr<const PackageID> >("origin_id"),
+ RepositoryName(v.member<std::string>("destination_repository_name")),
+ destringify<DestinationType>(v.member<std::string>("destination_type")),
+ replacing
+ ));
}
-const std::tr1::shared_ptr<const RequiredConfirmations>
-SimpleInstallJob::required_confirmations() const
-{
- return _imp->required_confirmations;
+void
+InstallJob::serialise(Serialiser & s) const
+{
+ s.object("InstallJob")
+ .member(SerialiserFlags<serialise::container, serialise::might_be_null>(), "requirements", requirements())
+ .member(SerialiserFlags<serialise::might_be_null>(), "origin_id", origin_id())
+ .member(SerialiserFlags<>(), "destination_repository_name", stringify(destination_repository_name()))
+ .member(SerialiserFlags<>(), "destination_type", stringify(destination_type()))
+ .member(SerialiserFlags<serialise::container, serialise::might_be_null>(), "replacing", replacing())
+ ;
}
-const std::tr1::shared_ptr<RequiredConfirmations>
-SimpleInstallJob::required_confirmations()
+namespace paludis
{
- return _imp->required_confirmations;
-}
+ template <>
+ struct Implementation<UninstallJob>
+ {
+ const std::tr1::shared_ptr<const JobRequirements> requirements;
+ const std::tr1::shared_ptr<const PackageIDSequence> ids_to_remove;
-const JobID
-SimpleInstallJob::id() const
-{
- return make_named_values<JobID>(
- n::string_id() = "install:" + stringify(resolution()->resolvent())
- );
-}
+ std::tr1::shared_ptr<JobState> state;
-void
-SimpleInstallJob::serialise(Serialiser & s) const
-{
- s.object("SimpleInstallJob")
- .member(SerialiserFlags<serialise::might_be_null, serialise::container>(), "arrows", arrows())
- .member(SerialiserFlags<serialise::might_be_null>(), "changes_to_make_decision", changes_to_make_decision())
- .member(SerialiserFlags<serialise::might_be_null>(), "resolution", resolution())
- .member(SerialiserFlags<serialise::container, serialise::might_be_null>(),
- "required_confirmations", required_confirmations())
- .member(SerialiserFlags<serialise::container, serialise::might_be_null>(),
- "used_existing_packages_when_ordering", used_existing_packages_when_ordering())
- ;
+ Implementation(
+ const std::tr1::shared_ptr<const JobRequirements> & q,
+ const std::tr1::shared_ptr<const PackageIDSequence> & r
+ ) :
+ requirements(q),
+ ids_to_remove(r)
+ {
+ }
+ };
}
-UninstallJob::UninstallJob(const std::tr1::shared_ptr<const Resolution> & r,
- const std::tr1::shared_ptr<const RemoveDecision> & d) :
- PrivateImplementationPattern<UninstallJob>(new Implementation<UninstallJob>(r, d))
+UninstallJob::UninstallJob(
+ const std::tr1::shared_ptr<const JobRequirements> & q,
+ const std::tr1::shared_ptr<const PackageIDSequence> & r
+ ) :
+ PrivateImplementationPattern<UninstallJob>(new Implementation<UninstallJob>(q, r))
{
}
@@ -585,159 +333,61 @@ UninstallJob::~UninstallJob()
{
}
-const std::tr1::shared_ptr<const Resolution>
-UninstallJob::resolution() const
+const std::tr1::shared_ptr<const PackageIDSequence>
+UninstallJob::ids_to_remove() const
{
- return _imp->resolution;
+ return _imp->ids_to_remove;
}
-const std::tr1::shared_ptr<const RemoveDecision>
-UninstallJob::remove_decision() const
+const std::tr1::shared_ptr<JobState>
+UninstallJob::state() const
{
- return _imp->decision;
+ return _imp->state;
}
-const std::tr1::shared_ptr<const ArrowSequence>
-UninstallJob::arrows() const
+void
+UninstallJob::set_state(const std::tr1::shared_ptr<JobState> & s)
{
- return _imp->arrows;
+ _imp->state = s;
}
-const std::tr1::shared_ptr<ArrowSequence>
-UninstallJob::arrows()
+const std::tr1::shared_ptr<const JobRequirements>
+UninstallJob::requirements() const
{
- return _imp->arrows;
+ return _imp->requirements;
}
-const std::tr1::shared_ptr<const JobIDSequence>
-UninstallJob::used_existing_packages_when_ordering() const
+const std::tr1::shared_ptr<UninstallJob>
+UninstallJob::deserialise(Deserialisation & d)
{
- return _imp->used_existing_packages_when_ordering;
-}
+ Deserialisator v(d, "UninstallJob");
-const std::tr1::shared_ptr<JobIDSequence>
-UninstallJob::used_existing_packages_when_ordering()
-{
- return _imp->used_existing_packages_when_ordering;
-}
-
-const std::tr1::shared_ptr<const RequiredConfirmations>
-UninstallJob::required_confirmations() const
-{
- return _imp->required_confirmations;
-}
+ std::tr1::shared_ptr<PackageIDSequence> ids_to_remove(new PackageIDSequence);
+ {
+ Deserialisator vv(*v.find_remove_member("ids_to_remove"), "c");
+ for (int n(1), n_end(vv.member<int>("count") + 1) ; n != n_end ; ++n)
+ ids_to_remove->push_back(vv.member<std::tr1::shared_ptr<const PackageID> >(stringify(n)));
+ }
-const std::tr1::shared_ptr<RequiredConfirmations>
-UninstallJob::required_confirmations()
-{
- return _imp->required_confirmations;
-}
+ std::tr1::shared_ptr<JobRequirements> requirements(new JobRequirements);
+ {
+ Deserialisator vv(*v.find_remove_member("requirements"), "c");
+ for (int n(1), n_end(vv.member<int>("count") + 1) ; n != n_end ; ++n)
+ requirements->push_back(vv.member<JobRequirement>(stringify(n)));
+ }
-const JobID
-UninstallJob::id() const
-{
- return make_named_values<JobID>(
- n::string_id() = "install:" + stringify(resolution()->resolvent())
- );
+ return make_shared_ptr(new UninstallJob(
+ requirements,
+ ids_to_remove
+ ));
}
void
UninstallJob::serialise(Serialiser & s) const
{
s.object("UninstallJob")
- .member(SerialiserFlags<serialise::might_be_null, serialise::container>(), "arrows", arrows())
- .member(SerialiserFlags<serialise::might_be_null>(), "remove_decision", remove_decision())
- .member(SerialiserFlags<serialise::might_be_null>(), "resolution", resolution())
- .member(SerialiserFlags<serialise::container, serialise::might_be_null>(),
- "required_confirmations", required_confirmations())
- .member(SerialiserFlags<serialise::container, serialise::might_be_null>(),
- "used_existing_packages_when_ordering", used_existing_packages_when_ordering())
- ;
-}
-
-ErrorJob::ErrorJob(const std::tr1::shared_ptr<const Resolution> & r, const std::tr1::shared_ptr<const UnableToMakeDecision> & d) :
- PrivateImplementationPattern<ErrorJob>(new Implementation<ErrorJob>(r, d))
-{
-}
-
-ErrorJob::~ErrorJob()
-{
-}
-
-const std::tr1::shared_ptr<const Resolution>
-ErrorJob::resolution() const
-{
- return _imp->resolution;
-}
-
-const std::tr1::shared_ptr<const ArrowSequence>
-ErrorJob::arrows() const
-{
- return _imp->arrows;
-}
-
-const std::tr1::shared_ptr<ArrowSequence>
-ErrorJob::arrows()
-{
- return _imp->arrows;
-}
-
-const std::tr1::shared_ptr<const JobIDSequence>
-ErrorJob::used_existing_packages_when_ordering() const
-{
- return _imp->used_existing_packages_when_ordering;
-}
-
-const std::tr1::shared_ptr<JobIDSequence>
-ErrorJob::used_existing_packages_when_ordering()
-{
- return _imp->used_existing_packages_when_ordering;
-}
-
-const std::tr1::shared_ptr<const RequiredConfirmations>
-ErrorJob::required_confirmations() const
-{
- return _imp->required_confirmations;
-}
-
-const std::tr1::shared_ptr<RequiredConfirmations>
-ErrorJob::required_confirmations()
-{
- return _imp->required_confirmations;
-}
-
-const JobID
-ErrorJob::id() const
-{
- return make_named_values<JobID>(
- n::string_id() = "error:" + stringify(resolution()->resolvent())
- );
-}
-
-void
-ErrorJob::serialise(Serialiser & s) const
-{
- s.object("ErrorJob")
- .member(SerialiserFlags<serialise::might_be_null, serialise::container>(), "arrows", arrows())
- .member(SerialiserFlags<serialise::might_be_null>(), "unable_to_make_decision", unable_to_make_decision())
- .member(SerialiserFlags<serialise::might_be_null>(), "resolution", resolution())
- .member(SerialiserFlags<serialise::container, serialise::might_be_null>(),
- "required_confirmations", required_confirmations())
- .member(SerialiserFlags<serialise::container, serialise::might_be_null>(),
- "used_existing_packages_when_ordering", used_existing_packages_when_ordering())
+ .member(SerialiserFlags<serialise::container, serialise::might_be_null>(), "requirements", requirements())
+ .member(SerialiserFlags<serialise::container, serialise::might_be_null>(), "ids_to_remove", ids_to_remove())
;
}
-const std::tr1::shared_ptr<const UnableToMakeDecision>
-ErrorJob::unable_to_make_decision() const
-{
- return _imp->decision;
-}
-
-template class PrivateImplementationPattern<resolver::UsableJob>;
-template class PrivateImplementationPattern<resolver::UsableGroupJob>;
-template class PrivateImplementationPattern<resolver::FetchJob>;
-template class PrivateImplementationPattern<resolver::SimpleInstallJob>;
-template class PrivateImplementationPattern<resolver::ErrorJob>;
-template class PrivateImplementationPattern<resolver::UninstallJob>;
-
diff --git a/paludis/resolver/job.hh b/paludis/resolver/job.hh
index bb3d2f0..a27bc17 100644
--- a/paludis/resolver/job.hh
+++ b/paludis/resolver/job.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009, 2010 Ciaran McCreesh
+ * 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
@@ -21,281 +21,126 @@
#define PALUDIS_GUARD_PALUDIS_RESOLVER_JOB_HH 1
#include <paludis/resolver/job-fwd.hh>
-#include <paludis/resolver/job_id-fwd.hh>
-#include <paludis/resolver/arrow-fwd.hh>
-#include <paludis/resolver/resolution-fwd.hh>
-#include <paludis/resolver/decision-fwd.hh>
-#include <paludis/resolver/required_confirmations-fwd.hh>
-#include <paludis/util/attributes.hh>
+#include <paludis/resolver/job_state-fwd.hh>
+#include <paludis/resolver/job_requirements-fwd.hh>
+#include <paludis/resolver/destination_types-fwd.hh>
+#include <paludis/util/private_implementation_pattern.hh>
#include <paludis/util/simple_visitor.hh>
#include <paludis/util/type_list.hh>
-#include <paludis/util/private_implementation_pattern.hh>
+#include <paludis/package_id-fwd.hh>
#include <paludis/serialise-fwd.hh>
+#include <paludis/name-fwd.hh>
#include <tr1/memory>
namespace paludis
{
namespace resolver
{
- class PALUDIS_VISIBLE Job :
- public virtual DeclareAbstractAcceptMethods<Job, MakeTypeList<
- UsableJob, UsableGroupJob, SimpleInstallJob, UninstallJob, FetchJob, ErrorJob>::Type>
- {
- public:
- virtual ~Job() = 0;
-
- virtual const JobID id()
- const PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
-
- virtual const std::tr1::shared_ptr<const ArrowSequence> arrows()
- const PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
-
- virtual const std::tr1::shared_ptr<ArrowSequence> arrows()
- PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
-
- virtual const std::tr1::shared_ptr<const JobIDSequence> used_existing_packages_when_ordering()
- const PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
-
- virtual const std::tr1::shared_ptr<JobIDSequence> used_existing_packages_when_ordering()
- PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
-
- virtual const std::tr1::shared_ptr<const RequiredConfirmations> required_confirmations()
- const PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
-
- virtual const std::tr1::shared_ptr<RequiredConfirmations> required_confirmations()
- PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
-
- virtual void serialise(Serialiser &) const = 0;
-
- static const std::tr1::shared_ptr<Job> deserialise(
- Deserialisation & d) PALUDIS_ATTRIBUTE((warn_unused_result));
- };
-
- class PALUDIS_VISIBLE UsableJob :
- public Job,
- public ImplementAcceptMethods<Job, UsableJob>,
- private PrivateImplementationPattern<UsableJob>
+ class PALUDIS_VISIBLE PretendJob :
+ private PrivateImplementationPattern<PretendJob>
{
public:
- UsableJob(const std::tr1::shared_ptr<const Resolution> &);
- ~UsableJob();
+ PretendJob(
+ const std::tr1::shared_ptr<const PackageID> &
+ );
+ ~PretendJob();
- virtual const JobID id() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ const std::tr1::shared_ptr<const PackageID> origin_id() const PALUDIS_ATTRIBUTE((warn_unused_result));
- virtual const std::tr1::shared_ptr<const ArrowSequence> arrows()
- const PALUDIS_ATTRIBUTE((warn_unused_result));
-
- virtual const std::tr1::shared_ptr<ArrowSequence> arrows()
- PALUDIS_ATTRIBUTE((warn_unused_result));
-
- virtual const std::tr1::shared_ptr<const JobIDSequence> used_existing_packages_when_ordering()
- const PALUDIS_ATTRIBUTE((warn_unused_result));
-
- virtual const std::tr1::shared_ptr<JobIDSequence> used_existing_packages_when_ordering()
- PALUDIS_ATTRIBUTE((warn_unused_result));
-
- virtual const std::tr1::shared_ptr<const RequiredConfirmations> required_confirmations()
- const PALUDIS_ATTRIBUTE((warn_unused_result));
-
- virtual const std::tr1::shared_ptr<RequiredConfirmations> required_confirmations()
- PALUDIS_ATTRIBUTE((warn_unused_result));
-
- const std::tr1::shared_ptr<const Resolution> resolution() const PALUDIS_ATTRIBUTE((warn_unused_result));
-
- virtual void serialise(Serialiser &) const;
+ static const std::tr1::shared_ptr<PretendJob> deserialise(Deserialisation &) PALUDIS_ATTRIBUTE((warn_unused_result));
+ void serialise(Serialiser &) const;
};
- class PALUDIS_VISIBLE UsableGroupJob :
- public Job,
- public ImplementAcceptMethods<Job, UsableGroupJob>,
- private PrivateImplementationPattern<UsableGroupJob>
+ class PALUDIS_VISIBLE ExecuteJob :
+ public virtual DeclareAbstractAcceptMethods<ExecuteJob, MakeTypeList<
+ FetchJob, InstallJob, UninstallJob>::Type>
{
public:
- UsableGroupJob(const std::tr1::shared_ptr<const JobIDSequence> &);
- ~UsableGroupJob();
+ virtual ~ExecuteJob();
- virtual const JobID id() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ virtual const std::tr1::shared_ptr<JobState> state() const PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
+ virtual void set_state(const std::tr1::shared_ptr<JobState> &) = 0;
- virtual const std::tr1::shared_ptr<const ArrowSequence> arrows()
- const PALUDIS_ATTRIBUTE((warn_unused_result));
+ virtual const std::tr1::shared_ptr<const JobRequirements> requirements() const PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
- virtual const std::tr1::shared_ptr<ArrowSequence> arrows()
- PALUDIS_ATTRIBUTE((warn_unused_result));
-
- virtual const std::tr1::shared_ptr<const JobIDSequence> used_existing_packages_when_ordering()
- const PALUDIS_ATTRIBUTE((warn_unused_result));
-
- virtual const std::tr1::shared_ptr<JobIDSequence> used_existing_packages_when_ordering()
- PALUDIS_ATTRIBUTE((warn_unused_result));
-
- virtual const std::tr1::shared_ptr<const RequiredConfirmations> required_confirmations()
- const PALUDIS_ATTRIBUTE((warn_unused_result));
-
- virtual const std::tr1::shared_ptr<RequiredConfirmations> required_confirmations()
- PALUDIS_ATTRIBUTE((warn_unused_result));
-
- const std::tr1::shared_ptr<const JobIDSequence> job_ids() const PALUDIS_ATTRIBUTE((warn_unused_result));
-
- virtual void serialise(Serialiser &) const;
+ static const std::tr1::shared_ptr<ExecuteJob> deserialise(Deserialisation &) PALUDIS_ATTRIBUTE((warn_unused_result));
+ virtual void serialise(Serialiser &) const = 0;
};
class PALUDIS_VISIBLE FetchJob :
- public Job,
- public ImplementAcceptMethods<Job, FetchJob>,
- private PrivateImplementationPattern<FetchJob>
+ private PrivateImplementationPattern<FetchJob>,
+ public ExecuteJob,
+ public ImplementAcceptMethods<ExecuteJob, FetchJob>
{
public:
FetchJob(
- const std::tr1::shared_ptr<const Resolution> &,
- const std::tr1::shared_ptr<const ChangesToMakeDecision> &);
+ const std::tr1::shared_ptr<const JobRequirements> &,
+ const std::tr1::shared_ptr<const PackageID> &
+ );
~FetchJob();
- virtual const JobID id() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ const std::tr1::shared_ptr<const PackageID> origin_id() const PALUDIS_ATTRIBUTE((warn_unused_result));
- virtual const std::tr1::shared_ptr<const ArrowSequence> arrows()
- const PALUDIS_ATTRIBUTE((warn_unused_result));
+ virtual const std::tr1::shared_ptr<JobState> state() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ virtual void set_state(const std::tr1::shared_ptr<JobState> &);
- virtual const std::tr1::shared_ptr<ArrowSequence> arrows()
- PALUDIS_ATTRIBUTE((warn_unused_result));
-
- virtual const std::tr1::shared_ptr<const JobIDSequence> used_existing_packages_when_ordering()
- const PALUDIS_ATTRIBUTE((warn_unused_result));
-
- virtual const std::tr1::shared_ptr<JobIDSequence> used_existing_packages_when_ordering()
- PALUDIS_ATTRIBUTE((warn_unused_result));
-
- virtual const std::tr1::shared_ptr<const RequiredConfirmations> required_confirmations()
- const PALUDIS_ATTRIBUTE((warn_unused_result));
-
- virtual const std::tr1::shared_ptr<RequiredConfirmations> required_confirmations()
- PALUDIS_ATTRIBUTE((warn_unused_result));
-
- const std::tr1::shared_ptr<const Resolution> resolution() const PALUDIS_ATTRIBUTE((warn_unused_result));
- const std::tr1::shared_ptr<const ChangesToMakeDecision> changes_to_make_decision() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ virtual const std::tr1::shared_ptr<const JobRequirements> requirements() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ static const std::tr1::shared_ptr<FetchJob> deserialise(Deserialisation &) PALUDIS_ATTRIBUTE((warn_unused_result));
virtual void serialise(Serialiser &) const;
};
- class PALUDIS_VISIBLE SimpleInstallJob :
- public Job,
- public ImplementAcceptMethods<Job, SimpleInstallJob>,
- private PrivateImplementationPattern<SimpleInstallJob>
+ class PALUDIS_VISIBLE InstallJob :
+ private PrivateImplementationPattern<InstallJob>,
+ public ExecuteJob,
+ public ImplementAcceptMethods<ExecuteJob, InstallJob>
{
public:
- SimpleInstallJob(
- const std::tr1::shared_ptr<const Resolution> &,
- const std::tr1::shared_ptr<const ChangesToMakeDecision> &);
- ~SimpleInstallJob();
-
- virtual const JobID id() const PALUDIS_ATTRIBUTE((warn_unused_result));
-
- virtual const std::tr1::shared_ptr<const ArrowSequence> arrows()
- const PALUDIS_ATTRIBUTE((warn_unused_result));
-
- virtual const std::tr1::shared_ptr<ArrowSequence> arrows()
- PALUDIS_ATTRIBUTE((warn_unused_result));
+ InstallJob(
+ const std::tr1::shared_ptr<const JobRequirements> &,
+ const std::tr1::shared_ptr<const PackageID> &,
+ const RepositoryName &,
+ const DestinationType,
+ const std::tr1::shared_ptr<const PackageIDSequence> &);
+ ~InstallJob();
- virtual const std::tr1::shared_ptr<const JobIDSequence> used_existing_packages_when_ordering()
- const PALUDIS_ATTRIBUTE((warn_unused_result));
+ const std::tr1::shared_ptr<const PackageID> origin_id() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ const RepositoryName destination_repository_name() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ DestinationType destination_type() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ const std::tr1::shared_ptr<const PackageIDSequence> replacing() const PALUDIS_ATTRIBUTE((warn_unused_result));
- virtual const std::tr1::shared_ptr<JobIDSequence> used_existing_packages_when_ordering()
- PALUDIS_ATTRIBUTE((warn_unused_result));
+ virtual const std::tr1::shared_ptr<JobState> state() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ virtual void set_state(const std::tr1::shared_ptr<JobState> &);
- virtual const std::tr1::shared_ptr<const RequiredConfirmations> required_confirmations()
- const PALUDIS_ATTRIBUTE((warn_unused_result));
-
- virtual const std::tr1::shared_ptr<RequiredConfirmations> required_confirmations()
- PALUDIS_ATTRIBUTE((warn_unused_result));
-
- const std::tr1::shared_ptr<const Resolution> resolution() const PALUDIS_ATTRIBUTE((warn_unused_result));
- const std::tr1::shared_ptr<const ChangesToMakeDecision> changes_to_make_decision() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ virtual const std::tr1::shared_ptr<const JobRequirements> requirements() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ static const std::tr1::shared_ptr<InstallJob> deserialise(Deserialisation &) PALUDIS_ATTRIBUTE((warn_unused_result));
virtual void serialise(Serialiser &) const;
};
class PALUDIS_VISIBLE UninstallJob :
- public Job,
- public ImplementAcceptMethods<Job, UninstallJob>,
- private PrivateImplementationPattern<UninstallJob>
+ private PrivateImplementationPattern<UninstallJob>,
+ public ExecuteJob,
+ public ImplementAcceptMethods<ExecuteJob, UninstallJob>
{
public:
UninstallJob(
- const std::tr1::shared_ptr<const Resolution> &,
- const std::tr1::shared_ptr<const RemoveDecision> &);
+ const std::tr1::shared_ptr<const JobRequirements> &,
+ const std::tr1::shared_ptr<const PackageIDSequence> &
+ );
~UninstallJob();
- virtual const JobID id() const PALUDIS_ATTRIBUTE((warn_unused_result));
-
- virtual const std::tr1::shared_ptr<const ArrowSequence> arrows()
- const PALUDIS_ATTRIBUTE((warn_unused_result));
-
- virtual const std::tr1::shared_ptr<ArrowSequence> arrows()
- PALUDIS_ATTRIBUTE((warn_unused_result));
+ const std::tr1::shared_ptr<const PackageIDSequence> ids_to_remove() const PALUDIS_ATTRIBUTE((warn_unused_result));
- virtual const std::tr1::shared_ptr<const JobIDSequence> used_existing_packages_when_ordering()
- const PALUDIS_ATTRIBUTE((warn_unused_result));
+ virtual const std::tr1::shared_ptr<JobState> state() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ virtual void set_state(const std::tr1::shared_ptr<JobState> &);
- virtual const std::tr1::shared_ptr<JobIDSequence> used_existing_packages_when_ordering()
- PALUDIS_ATTRIBUTE((warn_unused_result));
-
- virtual const std::tr1::shared_ptr<const RequiredConfirmations> required_confirmations()
- const PALUDIS_ATTRIBUTE((warn_unused_result));
-
- virtual const std::tr1::shared_ptr<RequiredConfirmations> required_confirmations()
- PALUDIS_ATTRIBUTE((warn_unused_result));
-
- const std::tr1::shared_ptr<const Resolution> resolution() const PALUDIS_ATTRIBUTE((warn_unused_result));
- const std::tr1::shared_ptr<const RemoveDecision> remove_decision() const PALUDIS_ATTRIBUTE((warn_unused_result));
-
- virtual void serialise(Serialiser &) const;
- };
-
- class PALUDIS_VISIBLE ErrorJob :
- public Job,
- public ImplementAcceptMethods<Job, ErrorJob>,
- private PrivateImplementationPattern<ErrorJob>
- {
- public:
- ErrorJob(
- const std::tr1::shared_ptr<const Resolution> &,
- const std::tr1::shared_ptr<const UnableToMakeDecision> &);
- ~ErrorJob();
-
- virtual const JobID id() const PALUDIS_ATTRIBUTE((warn_unused_result));
-
- virtual const std::tr1::shared_ptr<const ArrowSequence> arrows()
- const PALUDIS_ATTRIBUTE((warn_unused_result));
-
- virtual const std::tr1::shared_ptr<ArrowSequence> arrows()
- PALUDIS_ATTRIBUTE((warn_unused_result));
-
- virtual const std::tr1::shared_ptr<const JobIDSequence> used_existing_packages_when_ordering()
- const PALUDIS_ATTRIBUTE((warn_unused_result));
-
- virtual const std::tr1::shared_ptr<JobIDSequence> used_existing_packages_when_ordering()
- PALUDIS_ATTRIBUTE((warn_unused_result));
-
- virtual const std::tr1::shared_ptr<const RequiredConfirmations> required_confirmations()
- const PALUDIS_ATTRIBUTE((warn_unused_result));
-
- virtual const std::tr1::shared_ptr<RequiredConfirmations> required_confirmations()
- PALUDIS_ATTRIBUTE((warn_unused_result));
-
- const std::tr1::shared_ptr<const Resolution> resolution() const PALUDIS_ATTRIBUTE((warn_unused_result));
- const std::tr1::shared_ptr<const UnableToMakeDecision> unable_to_make_decision() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ virtual const std::tr1::shared_ptr<const JobRequirements> requirements() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ static const std::tr1::shared_ptr<UninstallJob> deserialise(Deserialisation &) PALUDIS_ATTRIBUTE((warn_unused_result));
virtual void serialise(Serialiser &) const;
};
}
-
-#ifdef PALUDIS_HAVE_EXTERN_TEMPLATE
- extern template class PrivateImplementationPattern<resolver::UsableJob>;
- extern template class PrivateImplementationPattern<resolver::UsableGroupJob>;
- extern template class PrivateImplementationPattern<resolver::FetchJob>;
- extern template class PrivateImplementationPattern<resolver::SimpleInstallJob>;
- extern template class PrivateImplementationPattern<resolver::UninstallJob>;
- extern template class PrivateImplementationPattern<resolver::ErrorJob>;
-#endif
}
#endif
diff --git a/paludis/resolver/job_id.cc b/paludis/resolver/job_id.cc
deleted file mode 100644
index 718854c..0000000
--- a/paludis/resolver/job_id.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-/* vim: set sw=4 sts=4 et foldmethod=syntax : */
-
-/*
- * Copyright (c) 2009, 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 <paludis/resolver/job_id.hh>
-#include <paludis/util/hashes.hh>
-#include <paludis/util/make_named_values.hh>
-#include <paludis/util/wrapped_forward_iterator-impl.hh>
-#include <paludis/util/sequence-impl.hh>
-#include <paludis/serialise-impl.hh>
-
-using namespace paludis;
-using namespace paludis::resolver;
-
-bool
-paludis::resolver::operator== (const JobID & a, const JobID & b)
-{
- return a.string_id() == b.string_id();
-}
-
-std::size_t
-JobID::hash() const
-{
- return Hash<std::string>()(string_id());
-}
-
-bool
-JobID::operator< (const JobID & other) const
-{
- return string_id() < other.string_id();
-}
-
-void
-JobID::serialise(Serialiser & s) const
-{
- s.object("JobID")
- .member(SerialiserFlags<>(), "string_id", string_id())
- ;
-}
-
-const JobID
-JobID::deserialise(Deserialisation & d)
-{
- Deserialisator v(d, "JobID");
- return make_named_values<JobID>(
- n::string_id() = v.member<std::string>("string_id")
- );
-}
-
-template class Sequence<JobID>;
-template class WrappedForwardIterator<JobIDSequence::ConstIteratorTag, const JobID>;
-
diff --git a/paludis/resolver/resolutions-fwd.hh b/paludis/resolver/job_list-fwd.hh
index 801e57f..da4256e 100644
--- a/paludis/resolver/resolutions-fwd.hh
+++ b/paludis/resolver/job_list-fwd.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009 Ciaran McCreesh
+ * 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
@@ -17,17 +17,17 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef PALUDIS_GUARD_PALUDIS_RESOLVER_RESOLUTIONS_FWD_HH
-#define PALUDIS_GUARD_PALUDIS_RESOLVER_RESOLUTIONS_FWD_HH 1
-
-#include <paludis/util/attributes.hh>
-#include <paludis/serialise-fwd.hh>
+#ifndef PALUDIS_GUARD_PALUDIS_RESOLVER_JOB_LIST_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_RESOLVER_JOB_LIST_FWD_HH 1
namespace paludis
{
namespace resolver
{
- struct Resolutions;
+ template <typename Job_>
+ struct JobList;
+
+ typedef int JobNumber;
}
}
diff --git a/paludis/resolver/job_list.cc b/paludis/resolver/job_list.cc
new file mode 100644
index 0000000..031c028
--- /dev/null
+++ b/paludis/resolver/job_list.cc
@@ -0,0 +1,124 @@
+/* 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 <paludis/resolver/job_list.hh>
+#include <paludis/resolver/job.hh>
+#include <paludis/util/private_implementation_pattern-impl.hh>
+#include <paludis/util/wrapped_forward_iterator-impl.hh>
+#include <paludis/serialise-impl.hh>
+#include <vector>
+
+using namespace paludis;
+using namespace paludis::resolver;
+
+namespace paludis
+{
+#ifndef PALUDIS_NO_DOUBLE_TEMPLATE
+ template <>
+#endif
+ template <typename Job_>
+ struct Implementation<JobList<Job_> >
+ {
+ std::vector<std::tr1::shared_ptr<Job_> > list;
+ };
+
+#ifdef PALUDIS_NO_DOUBLE_TEMPLATE
+ template <>
+#endif
+ template <typename Job_>
+ struct WrappedForwardIteratorTraits<JobListConstIteratorTag<Job_> >
+ {
+ typedef typename std::vector<std::tr1::shared_ptr<Job_> >::const_iterator UnderlyingIterator;
+ };
+}
+
+template <typename Job_>
+JobList<Job_>::JobList() :
+ PrivateImplementationPattern<JobList<Job_> >(new Implementation<JobList<Job_> >)
+{
+}
+
+template <typename Job_>
+JobList<Job_>::~JobList()
+{
+}
+
+template <typename Job_>
+JobNumber
+JobList<Job_>::append(const std::tr1::shared_ptr<Job_> & i)
+{
+ typename std::vector<std::tr1::shared_ptr<Job_> >::const_iterator p(_imp->list.insert(_imp->list.end(), i));
+ return p - _imp->list.begin();
+}
+
+template <typename Job_>
+int
+JobList<Job_>::length() const
+{
+ return _imp->list.size();
+}
+
+template <typename Job_>
+typename JobList<Job_>::ConstIterator
+JobList<Job_>::begin() const
+{
+ return ConstIterator(_imp->list.begin());
+}
+
+template <typename Job_>
+typename JobList<Job_>::ConstIterator
+JobList<Job_>::end() const
+{
+ return ConstIterator(_imp->list.end());
+}
+
+template <typename Job_>
+typename JobList<Job_>::ConstIterator
+JobList<Job_>::fetch(const JobNumber n) const
+{
+ return ConstIterator(_imp->list.begin() + n);
+}
+
+template <typename Job_>
+const std::tr1::shared_ptr<JobList<Job_> >
+JobList<Job_>::deserialise(Deserialisation & d)
+{
+ Deserialisator v(d, "JobList");
+ Deserialisator vv(*v.find_remove_member("items"), "c");
+ std::tr1::shared_ptr<JobList> result(new JobList);
+ for (int n(1), n_end(vv.member<int>("count") + 1) ; n != n_end ; ++n)
+ result->append(vv.member<std::tr1::shared_ptr<Job_> >(stringify(n)));
+ return result;
+}
+
+template <typename Job_>
+void
+JobList<Job_>::serialise(Serialiser & s) const
+{
+ s.object("JobList")
+ .member(SerialiserFlags<serialise::container>(), "items", _imp->list)
+ ;
+}
+
+template class JobList<PretendJob>;
+template class WrappedForwardIterator<JobListConstIteratorTag<PretendJob>, const std::tr1::shared_ptr<PretendJob> >;
+
+template class JobList<ExecuteJob>;
+template class WrappedForwardIterator<JobListConstIteratorTag<ExecuteJob>, const std::tr1::shared_ptr<ExecuteJob> >;
+
diff --git a/paludis/resolver/job_list.hh b/paludis/resolver/job_list.hh
new file mode 100644
index 0000000..a2bc464
--- /dev/null
+++ b/paludis/resolver/job_list.hh
@@ -0,0 +1,76 @@
+/* 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_PALUDIS_RESOLVER_JOB_LIST_HH
+#define PALUDIS_GUARD_PALUDIS_RESOLVER_JOB_LIST_HH 1
+
+#include <paludis/resolver/job_list-fwd.hh>
+#include <paludis/resolver/job-fwd.hh>
+#include <paludis/util/private_implementation_pattern.hh>
+#include <paludis/util/wrapped_forward_iterator.hh>
+#include <paludis/serialise-fwd.hh>
+#include <tr1/memory>
+
+namespace paludis
+{
+ namespace resolver
+ {
+ template <typename Job_>
+ struct JobListConstIteratorTag;
+
+ template <typename Job_>
+ class PALUDIS_VISIBLE JobList :
+ private PrivateImplementationPattern<JobList<Job_> >
+ {
+ private:
+ using PrivateImplementationPattern<JobList<Job_> >::_imp;
+
+ public:
+ JobList();
+ ~JobList();
+
+ JobNumber append(const std::tr1::shared_ptr<Job_> &);
+
+ int length() const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ typedef JobListConstIteratorTag<Job_> ConstIteratorTag;
+ typedef WrappedForwardIterator<ConstIteratorTag, const std::tr1::shared_ptr<Job_> > ConstIterator;
+ ConstIterator begin() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ ConstIterator end() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ ConstIterator fetch(const JobNumber) const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ static const std::tr1::shared_ptr<JobList<Job_> > deserialise(Deserialisation &) PALUDIS_ATTRIBUTE((warn_unused_result));
+ void serialise(Serialiser &) const;
+ };
+
+#ifdef PALUDIS_HAVE_EXTERN_TEMPLATE
+ extern template class JobList<PretendJob>;
+ extern template class JobList<ExecuteJob>;
+#endif
+ }
+
+#ifdef PALUDIS_HAVE_EXTERN_TEMPLATE
+ extern template class WrappedForwardIterator<resolver::JobListConstIteratorTag<resolver::PretendJob>,
+ const std::tr1::shared_ptr<resolver::PretendJob> >;
+ extern template class WrappedForwardIterator<resolver::JobListConstIteratorTag<resolver::ExecuteJob>,
+ const std::tr1::shared_ptr<resolver::ExecuteJob> >;
+#endif
+}
+
+#endif
diff --git a/paludis/resolver/jobs-fwd.hh b/paludis/resolver/job_lists-fwd.hh
index bde750c..2587221 100644
--- a/paludis/resolver/jobs-fwd.hh
+++ b/paludis/resolver/job_lists-fwd.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009 Ciaran McCreesh
+ * 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
@@ -17,14 +17,14 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef PALUDIS_GUARD_PALUDIS_RESOLVER_JOBS_FWD_HH
-#define PALUDIS_GUARD_PALUDIS_RESOLVER_JOBS_FWD_HH 1
+#ifndef PALUDIS_GUARD_PALUDIS_RESOLVER_JOB_LISTS_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_RESOLVER_JOB_LISTS_FWD_HH 1
namespace paludis
{
namespace resolver
{
- struct Jobs;
+ struct JobLists;
}
}
diff --git a/paludis/resolver/job_lists.cc b/paludis/resolver/job_lists.cc
new file mode 100644
index 0000000..9552ee3
--- /dev/null
+++ b/paludis/resolver/job_lists.cc
@@ -0,0 +1,48 @@
+/* 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 <paludis/resolver/job_lists.hh>
+#include <paludis/resolver/job_list.hh>
+#include <paludis/util/make_named_values.hh>
+#include <paludis/util/make_shared_copy.hh>
+#include <paludis/serialise-impl.hh>
+
+using namespace paludis;
+using namespace paludis::resolver;
+
+void
+JobLists::serialise(Serialiser & s) const
+{
+ s.object("JobLists")
+ .member(SerialiserFlags<serialise::might_be_null>(), "execute_job_list", execute_job_list())
+ .member(SerialiserFlags<serialise::might_be_null>(), "pretend_job_list", pretend_job_list())
+ ;
+}
+
+const std::tr1::shared_ptr<JobLists>
+JobLists::deserialise(Deserialisation & d)
+{
+ Deserialisator v(d, "JobLists");
+
+ return make_shared_copy(make_named_values<JobLists>(
+ n::execute_job_list() = v.member<std::tr1::shared_ptr<JobList<ExecuteJob> > >("execute_job_list"),
+ n::pretend_job_list() = v.member<std::tr1::shared_ptr<JobList<PretendJob> > >("pretend_job_list")
+ ));
+}
+
diff --git a/paludis/resolver/arrow.hh b/paludis/resolver/job_lists.hh
index 256ccb1..10f5f4d 100644
--- a/paludis/resolver/arrow.hh
+++ b/paludis/resolver/job_lists.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009, 2010 Ciaran McCreesh
+ * 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
@@ -17,37 +17,33 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef PALUDIS_GUARD_PALUDIS_RESOLVER_ARROW_HH
-#define PALUDIS_GUARD_PALUDIS_RESOLVER_ARROW_HH 1
+#ifndef PALUDIS_GUARD_PALUDIS_RESOLVER_JOB_LISTS_HH
+#define PALUDIS_GUARD_PALUDIS_RESOLVER_JOB_LISTS_HH 1
-#include <paludis/resolver/arrow-fwd.hh>
-#include <paludis/resolver/resolvent.hh>
-#include <paludis/resolver/reason-fwd.hh>
-#include <paludis/resolver/job_id.hh>
-#include <paludis/resolver/failure_kinds-fwd.hh>
-#include <paludis/serialise-fwd.hh>
+#include <paludis/resolver/job_lists-fwd.hh>
+#include <paludis/resolver/job_list-fwd.hh>
+#include <paludis/resolver/job-fwd.hh>
#include <paludis/util/named_value.hh>
+#include <paludis/serialise-fwd.hh>
+#include <tr1/memory>
namespace paludis
{
namespace n
{
- typedef Name<struct comes_after_name> comes_after;
- typedef Name<struct failure_kinds_name> failure_kinds;
- typedef Name<struct maybe_reason_name> maybe_reason;
+ typedef Name<struct execute_job_list_name> execute_job_list;
+ typedef Name<struct pretend_job_list_name> pretend_job_list;
}
namespace resolver
{
- struct Arrow
+ struct JobLists
{
- NamedValue<n::comes_after, JobID> comes_after;
- NamedValue<n::failure_kinds, FailureKinds> failure_kinds;
- NamedValue<n::maybe_reason, std::tr1::shared_ptr<const Reason> > maybe_reason;
+ NamedValue<n::execute_job_list, std::tr1::shared_ptr<JobList<ExecuteJob> > > execute_job_list;
+ NamedValue<n::pretend_job_list, std::tr1::shared_ptr<JobList<PretendJob> > > pretend_job_list;
+ static const std::tr1::shared_ptr<JobLists> deserialise(Deserialisation &) PALUDIS_ATTRIBUTE((warn_unused_result));
void serialise(Serialiser &) const;
-
- static const Arrow deserialise(Deserialisation & d) PALUDIS_ATTRIBUTE((warn_unused_result));
};
}
}
diff --git a/paludis/resolver/job_id-fwd.hh b/paludis/resolver/job_requirements-fwd.hh
index a027329..4c974d8 100644
--- a/paludis/resolver/job_id-fwd.hh
+++ b/paludis/resolver/job_requirements-fwd.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009 Ciaran McCreesh
+ * 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
@@ -17,21 +17,24 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef PALUDIS_GUARD_PALUDIS_RESOLVER_JOB_ID_FWD_HH
-#define PALUDIS_GUARD_PALUDIS_RESOLVER_JOB_ID_FWD_HH 1
+#ifndef PALUDIS_GUARD_PALUDIS_RESOLVER_JOB_REQUIREMENTS_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_RESOLVER_JOB_REQUIREMENTS_FWD_HH 1
#include <paludis/util/sequence-fwd.hh>
+#include <paludis/util/options-fwd.hh>
#include <paludis/util/attributes.hh>
+#include <iosfwd>
namespace paludis
{
namespace resolver
{
- struct JobID;
+#include <paludis/resolver/job_requirements-se.hh>
- bool operator== (const JobID &, const JobID &) PALUDIS_VISIBLE PALUDIS_ATTRIBUTE((warn_unused_result));
+ typedef Options<JobRequirementIf> JobRequirementIfs;
- typedef Sequence<JobID> JobIDSequence;
+ struct JobRequirement;
+ typedef Sequence<JobRequirement> JobRequirements;
}
}
diff --git a/paludis/resolver/arrow.cc b/paludis/resolver/job_requirements.cc
index 1390c25..7fda1d0 100644
--- a/paludis/resolver/arrow.cc
+++ b/paludis/resolver/job_requirements.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009, 2010 Ciaran McCreesh
+ * 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
@@ -17,37 +17,40 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <paludis/resolver/arrow.hh>
-#include <paludis/resolver/reason.hh>
-#include <paludis/util/sequence-impl.hh>
+#include <paludis/resolver/job_requirements.hh>
+#include <paludis/util/exception.hh>
+#include <paludis/util/stringify.hh>
#include <paludis/util/wrapped_forward_iterator-impl.hh>
+#include <paludis/util/sequence-impl.hh>
#include <paludis/util/make_named_values.hh>
#include <paludis/serialise-impl.hh>
+#include <istream>
+#include <ostream>
using namespace paludis;
using namespace paludis::resolver;
-void
-Arrow::serialise(Serialiser & s) const
+#include <paludis/resolver/job_requirements-se.cc>
+
+const JobRequirement
+JobRequirement::deserialise(Deserialisation & d)
{
- s.object("Arrow")
- .member(SerialiserFlags<>(), "comes_after", comes_after())
- .member(SerialiserFlags<>(), "failure_kinds", failure_kinds())
- .member(SerialiserFlags<serialise::might_be_null>(), "maybe_reason", maybe_reason())
- ;
+ Deserialisator v(d, "JobRequirement");
+ return make_named_values<JobRequirement>(
+ n::job_number() = v.member<JobNumber>("job_number"),
+ n::required_if() = v.member<JobRequirementIfs>("required_if")
+ );
}
-const Arrow
-Arrow::deserialise(Deserialisation & d)
+void
+JobRequirement::serialise(Serialiser & s) const
{
- Deserialisator v(d, "Arrow");
- return make_named_values<Arrow>(
- n::comes_after() = v.member<JobID>("comes_after"),
- n::failure_kinds() = v.member<FailureKinds>("failure_kinds"),
- n::maybe_reason() = v.member<std::tr1::shared_ptr<const Reason> >("maybe_reason")
- );
+ s.object("JobRequirement")
+ .member(SerialiserFlags<>(), "job_number", job_number())
+ .member(SerialiserFlags<>(), "required_if", required_if())
+ ;
}
-template class Sequence<Arrow>;
-template class WrappedForwardIterator<ArrowSequence::ConstIteratorTag, const Arrow>;
+template class Sequence<JobRequirement>;
+template class WrappedForwardIterator<Sequence<JobRequirement>::ConstIteratorTag, const JobRequirement>;
diff --git a/paludis/resolver/job_requirements.hh b/paludis/resolver/job_requirements.hh
new file mode 100644
index 0000000..cd31777
--- /dev/null
+++ b/paludis/resolver/job_requirements.hh
@@ -0,0 +1,57 @@
+/* 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_PALUDIS_RESOLVER_JOB_REQUIREMENTS_HH
+#define PALUDIS_GUARD_PALUDIS_RESOLVER_JOB_REQUIREMENTS_HH 1
+
+#include <paludis/resolver/job_requirements-fwd.hh>
+#include <paludis/resolver/job_list-fwd.hh>
+#include <paludis/util/options.hh>
+#include <paludis/util/named_value.hh>
+#include <paludis/util/sequence.hh>
+#include <paludis/util/wrapped_forward_iterator.hh>
+#include <paludis/serialise-fwd.hh>
+
+namespace paludis
+{
+ namespace n
+ {
+ typedef Name<struct job_number_name> job_number;
+ typedef Name<struct required_if_name> required_if;
+ }
+
+ namespace resolver
+ {
+ struct JobRequirement
+ {
+ NamedValue<n::job_number, JobNumber> job_number;
+ NamedValue<n::required_if, JobRequirementIfs> required_if;
+
+ static const JobRequirement deserialise(Deserialisation & d) PALUDIS_ATTRIBUTE((warn_unused_result));
+ void serialise(Serialiser &) const;
+ };
+ }
+
+#ifdef PALUDIS_HAVE_EXTERN_TEMPLATE
+ extern template class Sequence<resolver::JobRequirement>;
+ extern template class WrappedForwardIterator<Sequence<resolver::JobRequirement>::ConstIteratorTag, const resolver::JobRequirement>;
+#endif
+}
+
+#endif
diff --git a/paludis/resolver/job_requirements.se b/paludis/resolver/job_requirements.se
new file mode 100644
index 0000000..ab9b52d
--- /dev/null
+++ b/paludis/resolver/job_requirements.se
@@ -0,0 +1,16 @@
+#!/usr/bin/env bash
+# vim: set sw=4 sts=4 et ft=sh :
+
+make_enum_JobRequirementIf()
+{
+ prefix jri
+ namespace paludis::resolver
+
+ key jri_require_for_satisfied "Require it if we're in if-satisfied mode"
+ key jri_require_for_independent "Require it if we're in if-independent mode"
+ key jri_require_always "Always require it"
+
+ want_destringify
+}
+
+
diff --git a/paludis/resolver/job_state-fwd.hh b/paludis/resolver/job_state-fwd.hh
index fab624e..2970e5f 100644
--- a/paludis/resolver/job_state-fwd.hh
+++ b/paludis/resolver/job_state-fwd.hh
@@ -25,7 +25,9 @@ namespace paludis
namespace resolver
{
struct JobState;
+
struct JobPendingState;
+ struct JobActiveState;
struct JobSucceededState;
struct JobFailedState;
struct JobSkippedState;
diff --git a/paludis/resolver/job_state.cc b/paludis/resolver/job_state.cc
index c3e63f1..78ae200 100644
--- a/paludis/resolver/job_state.cc
+++ b/paludis/resolver/job_state.cc
@@ -19,40 +19,26 @@
#include <paludis/resolver/job_state.hh>
#include <paludis/util/private_implementation_pattern-impl.hh>
-#include <paludis/util/indirect_iterator-impl.hh>
-#include <paludis/output_manager.hh>
-#include <list>
-#include <algorithm>
-#include <tr1/functional>
+#include <paludis/util/make_shared_ptr.hh>
using namespace paludis;
using namespace paludis::resolver;
-JobState::~JobState()
-{
-}
-
namespace paludis
{
template <>
- struct Implementation<JobPendingState>
+ struct Implementation<JobActiveState>
{
- const std::tr1::shared_ptr<const Job> job;
-
- Implementation(const std::tr1::shared_ptr<const Job> & j) :
- job(j)
- {
- }
+ std::tr1::shared_ptr<OutputManager> output_manager;
};
template <>
struct Implementation<JobSucceededState>
{
- const std::tr1::shared_ptr<const Job> job;
- std::list<std::tr1::shared_ptr<OutputManager> > output_managers;
+ const std::tr1::shared_ptr<OutputManager> output_manager;
- Implementation(const std::tr1::shared_ptr<const Job> & j) :
- job(j)
+ Implementation(const std::tr1::shared_ptr<OutputManager> & m) :
+ output_manager(m)
{
}
};
@@ -60,143 +46,73 @@ namespace paludis
template <>
struct Implementation<JobFailedState>
{
- const std::tr1::shared_ptr<const Job> job;
- std::list<std::tr1::shared_ptr<OutputManager> > output_managers;
+ const std::tr1::shared_ptr<OutputManager> output_manager;
- Implementation(const std::tr1::shared_ptr<const Job> & j) :
- job(j)
+ Implementation(const std::tr1::shared_ptr<OutputManager> & m) :
+ output_manager(m)
{
}
};
-
- template <>
- struct Implementation<JobSkippedState>
- {
- const std::tr1::shared_ptr<const Job> job;
-
- Implementation(const std::tr1::shared_ptr<const Job> & j) :
- job(j)
- {
- }
- };
-}
-
-JobPendingState::JobPendingState(const std::tr1::shared_ptr<const Job> & j) :
- PrivateImplementationPattern<JobPendingState>(new Implementation<JobPendingState>(j))
-{
-}
-
-JobPendingState::~JobPendingState()
-{
-}
-
-const std::tr1::shared_ptr<const Job>
-JobPendingState::job() const
-{
- return _imp->job;
}
-const std::string
-JobPendingState::state_name() const
-{
- return "pending";
-}
-
-JobSucceededState::JobSucceededState(const std::tr1::shared_ptr<const Job> & j) :
- PrivateImplementationPattern<JobSucceededState>(new Implementation<JobSucceededState>(j))
-{
-}
-
-JobSucceededState::~JobSucceededState()
+JobState::~JobState()
{
}
-const std::tr1::shared_ptr<const Job>
-JobSucceededState::job() const
+JobActiveState::JobActiveState() :
+ PrivateImplementationPattern<JobActiveState>(new Implementation<JobActiveState>)
{
- return _imp->job;
}
-const std::string
-JobSucceededState::state_name() const
+JobActiveState::~JobActiveState()
{
- return "succeeded";
}
void
-JobSucceededState::add_output_manager(const std::tr1::shared_ptr<OutputManager> & o)
-{
- _imp->output_managers.push_back(o);
-}
-
-bool
-JobSucceededState::any_output_manager_wants_to_flush() const
+JobActiveState::set_output_manager(const std::tr1::shared_ptr<OutputManager> & m)
{
- return indirect_iterator(_imp->output_managers.end()) != std::find_if(
- indirect_iterator(_imp->output_managers.begin()),
- indirect_iterator(_imp->output_managers.end()),
- std::tr1::bind(&OutputManager::want_to_flush, std::tr1::placeholders::_1));
+ _imp->output_manager = m;
}
-JobFailedState::JobFailedState(const std::tr1::shared_ptr<const Job> & j) :
- PrivateImplementationPattern<JobFailedState>(new Implementation<JobFailedState>(j))
+const std::tr1::shared_ptr<JobSucceededState>
+JobActiveState::succeeded() const
{
+ return make_shared_ptr(new JobSucceededState(_imp->output_manager));
}
-JobFailedState::~JobFailedState()
-{
-}
-
-const std::tr1::shared_ptr<const Job>
-JobFailedState::job() const
+const std::tr1::shared_ptr<JobFailedState>
+JobActiveState::failed() const
{
- return _imp->job;
+ return make_shared_ptr(new JobFailedState(_imp->output_manager));
}
-void
-JobFailedState::add_output_manager(const std::tr1::shared_ptr<OutputManager> & o)
+JobSucceededState::JobSucceededState(const std::tr1::shared_ptr<OutputManager> & m) :
+ PrivateImplementationPattern<JobSucceededState>(new Implementation<JobSucceededState>(m))
{
- _imp->output_managers.push_back(o);
}
-bool
-JobFailedState::any_output_manager_wants_to_flush() const
-{
- return indirect_iterator(_imp->output_managers.end()) != std::find_if(
- indirect_iterator(_imp->output_managers.begin()),
- indirect_iterator(_imp->output_managers.end()),
- std::tr1::bind(&OutputManager::want_to_flush, std::tr1::placeholders::_1));
-}
-
-const std::string
-JobFailedState::state_name() const
+JobSucceededState::~JobSucceededState()
{
- return "failed";
}
-JobSkippedState::JobSkippedState(const std::tr1::shared_ptr<const Job> & j) :
- PrivateImplementationPattern<JobSkippedState>(new Implementation<JobSkippedState>(j))
+const std::tr1::shared_ptr<OutputManager>
+JobSucceededState::output_manager() const
{
+ return _imp->output_manager;
}
-JobSkippedState::~JobSkippedState()
+JobFailedState::JobFailedState(const std::tr1::shared_ptr<OutputManager> & m) :
+ PrivateImplementationPattern<JobFailedState>(new Implementation<JobFailedState>(m))
{
}
-const std::tr1::shared_ptr<const Job>
-JobSkippedState::job() const
+JobFailedState::~JobFailedState()
{
- return _imp->job;
}
-const std::string
-JobSkippedState::state_name() const
+const std::tr1::shared_ptr<OutputManager>
+JobFailedState::output_manager() const
{
- return "skipped";
+ return _imp->output_manager;
}
-template class PrivateImplementationPattern<JobPendingState>;
-template class PrivateImplementationPattern<JobSucceededState>;
-template class PrivateImplementationPattern<JobFailedState>;
-template class PrivateImplementationPattern<JobSkippedState>;
-
diff --git a/paludis/resolver/job_state.hh b/paludis/resolver/job_state.hh
index c3c946d..8e3a8c0 100644
--- a/paludis/resolver/job_state.hh
+++ b/paludis/resolver/job_state.hh
@@ -21,13 +21,11 @@
#define PALUDIS_GUARD_PALUDIS_RESOLVER_JOB_STATE_HH 1
#include <paludis/resolver/job_state-fwd.hh>
-#include <paludis/resolver/job-fwd.hh>
-#include <paludis/util/private_implementation_pattern.hh>
#include <paludis/util/simple_visitor.hh>
#include <paludis/util/type_list.hh>
+#include <paludis/util/private_implementation_pattern.hh>
#include <paludis/output_manager-fwd.hh>
#include <tr1/memory>
-#include <string>
namespace paludis
{
@@ -35,82 +33,62 @@ namespace paludis
{
class PALUDIS_VISIBLE JobState :
public virtual DeclareAbstractAcceptMethods<JobState, MakeTypeList<
- JobPendingState, JobSucceededState, JobFailedState, JobSkippedState>::Type>
+ JobPendingState, JobActiveState, JobSucceededState, JobFailedState, JobSkippedState>::Type>
{
public:
virtual ~JobState() = 0;
-
- virtual const std::tr1::shared_ptr<const Job> job() const
- PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
-
- virtual const std::string state_name() const PALUDIS_ATTRIBUTE((warn_unused_result)) = 0;
};
class PALUDIS_VISIBLE JobPendingState :
public JobState,
- public ImplementAcceptMethods<JobState, JobPendingState>,
- private PrivateImplementationPattern<JobPendingState>
+ public ImplementAcceptMethods<JobState, JobPendingState>
+ {
+ };
+
+ class PALUDIS_VISIBLE JobActiveState :
+ private PrivateImplementationPattern<JobActiveState>,
+ public JobState,
+ public ImplementAcceptMethods<JobState, JobActiveState>
{
public:
- JobPendingState(const std::tr1::shared_ptr<const Job> &);
- ~JobPendingState();
+ JobActiveState();
+ ~JobActiveState();
- virtual const std::tr1::shared_ptr<const Job> job() const PALUDIS_ATTRIBUTE((warn_unused_result));
- virtual const std::string state_name() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ void set_output_manager(const std::tr1::shared_ptr<OutputManager> &);
+ const std::tr1::shared_ptr<JobSucceededState> succeeded() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ const std::tr1::shared_ptr<JobFailedState> failed() const PALUDIS_ATTRIBUTE((warn_unused_result));
};
class PALUDIS_VISIBLE JobSucceededState :
+ private PrivateImplementationPattern<JobSucceededState>,
public JobState,
- public ImplementAcceptMethods<JobState, JobSucceededState>,
- private PrivateImplementationPattern<JobSucceededState>
+ public ImplementAcceptMethods<JobState, JobSucceededState>
{
public:
- JobSucceededState(const std::tr1::shared_ptr<const Job> &);
+ JobSucceededState(const std::tr1::shared_ptr<OutputManager> &);
~JobSucceededState();
- virtual const std::tr1::shared_ptr<const Job> job() const PALUDIS_ATTRIBUTE((warn_unused_result));
- virtual const std::string state_name() const PALUDIS_ATTRIBUTE((warn_unused_result));
-
- void add_output_manager(const std::tr1::shared_ptr<OutputManager> &);
- bool any_output_manager_wants_to_flush() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ const std::tr1::shared_ptr<OutputManager> output_manager() const PALUDIS_ATTRIBUTE((warn_unused_result));
};
class PALUDIS_VISIBLE JobFailedState :
+ private PrivateImplementationPattern<JobFailedState>,
public JobState,
- public ImplementAcceptMethods<JobState, JobFailedState>,
- private PrivateImplementationPattern<JobFailedState>
+ public ImplementAcceptMethods<JobState, JobFailedState>
{
public:
- JobFailedState(const std::tr1::shared_ptr<const Job> &);
+ JobFailedState(const std::tr1::shared_ptr<OutputManager> &);
~JobFailedState();
- virtual const std::tr1::shared_ptr<const Job> job() const PALUDIS_ATTRIBUTE((warn_unused_result));
- virtual const std::string state_name() const PALUDIS_ATTRIBUTE((warn_unused_result));
-
- void add_output_manager(const std::tr1::shared_ptr<OutputManager> &);
- bool any_output_manager_wants_to_flush() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ const std::tr1::shared_ptr<OutputManager> output_manager() const PALUDIS_ATTRIBUTE((warn_unused_result));
};
class PALUDIS_VISIBLE JobSkippedState :
public JobState,
- public ImplementAcceptMethods<JobState, JobSkippedState>,
- private PrivateImplementationPattern<JobSkippedState>
+ public ImplementAcceptMethods<JobState, JobSkippedState>
{
- public:
- JobSkippedState(const std::tr1::shared_ptr<const Job> &);
- ~JobSkippedState();
-
- virtual const std::tr1::shared_ptr<const Job> job() const PALUDIS_ATTRIBUTE((warn_unused_result));
- virtual const std::string state_name() const PALUDIS_ATTRIBUTE((warn_unused_result));
};
}
-
-#ifdef PALUDIS_HAVE_EXTERN_TEMPLATE
- extern template class PrivateImplementationPattern<resolver::JobPendingState>;
- extern template class PrivateImplementationPattern<resolver::JobSucceededState>;
- extern template class PrivateImplementationPattern<resolver::JobFailedState>;
- extern template class PrivateImplementationPattern<resolver::JobSkippedState>;
-#endif
}
#endif
diff --git a/paludis/resolver/jobs.cc b/paludis/resolver/jobs.cc
deleted file mode 100644
index 3ada174..0000000
--- a/paludis/resolver/jobs.cc
+++ /dev/null
@@ -1,299 +0,0 @@
-/* vim: set sw=4 sts=4 et foldmethod=syntax : */
-
-/*
- * Copyright (c) 2009, 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 <paludis/resolver/jobs.hh>
-#include <paludis/resolver/job.hh>
-#include <paludis/resolver/job_id.hh>
-#include <paludis/resolver/resolution.hh>
-#include <paludis/util/private_implementation_pattern-impl.hh>
-#include <paludis/util/hashes.hh>
-#include <paludis/util/stringify.hh>
-#include <paludis/util/exception.hh>
-#include <paludis/util/simple_visitor_cast.hh>
-#include <paludis/serialise-impl.hh>
-#include <tr1/unordered_map>
-#include <list>
-#include <map>
-
-using namespace paludis;
-using namespace paludis::resolver;
-
-typedef std::list<std::tr1::shared_ptr<Job> > JobsList;
-typedef std::multimap<Resolvent, JobsList::const_iterator> JobsListByResolventIndex;
-typedef std::tr1::unordered_map<JobID, JobsList::const_iterator, Hash<JobID> > JobsListByJobIDIndex;
-
-namespace paludis
-{
- template <>
- struct Implementation<Jobs>
- {
- JobsList jobs;
- JobsListByResolventIndex jobs_list_by_resolvent_index;
- JobsListByJobIDIndex jobs_list_by_job_id_index;
- };
-}
-
-Jobs::Jobs() :
- PrivateImplementationPattern<Jobs>(new Implementation<Jobs>)
-{
-}
-
-Jobs::~Jobs()
-{
-}
-
-namespace
-{
- struct Indexer
- {
- JobsListByResolventIndex & jobs_list_by_resolvent_index;
- JobsList::const_iterator i;
-
- Indexer(JobsListByResolventIndex & j, const JobsList::const_iterator & c) :
- jobs_list_by_resolvent_index(j),
- i(c)
- {
- }
-
- void visit(const UsableJob & j)
- {
- jobs_list_by_resolvent_index.insert(std::make_pair(j.resolution()->resolvent(), i));
- }
-
- void visit(const UninstallJob & j)
- {
- jobs_list_by_resolvent_index.insert(std::make_pair(j.resolution()->resolvent(), i));
- }
-
- void visit(const UsableGroupJob &)
- {
- }
-
- void visit(const SimpleInstallJob & j)
- {
- jobs_list_by_resolvent_index.insert(std::make_pair(j.resolution()->resolvent(), i));
- }
-
- void visit(const ErrorJob & j)
- {
- jobs_list_by_resolvent_index.insert(std::make_pair(j.resolution()->resolvent(), i));
- }
-
- void visit(const FetchJob & j)
- {
- jobs_list_by_resolvent_index.insert(std::make_pair(j.resolution()->resolvent(), i));
- }
- };
-}
-
-void
-Jobs::add(const std::tr1::shared_ptr<Job> & j)
-{
- JobsList::const_iterator i(_imp->jobs.insert(_imp->jobs.end(), j));
- Indexer x(_imp->jobs_list_by_resolvent_index, i);
- j->accept(x);
- _imp->jobs_list_by_job_id_index.insert(std::make_pair(j->id(), i));
-}
-
-namespace
-{
- struct InstalledJobChecker
- {
- bool visit(const FetchJob &) const
- {
- return false;
- }
-
- bool visit(const ErrorJob &) const
- {
- return true;
- }
-
- bool visit(const UninstallJob &) const
- {
- return true;
- }
-
- bool visit(const UsableJob &) const
- {
- return false;
- }
-
- bool visit(const UsableGroupJob &) const
- {
- return false;
- }
-
- bool visit(const SimpleInstallJob &) const
- {
- return true;
- }
- };
-
- struct UsableJobChecker
- {
- bool visit(const FetchJob &) const
- {
- return false;
- }
-
- bool visit(const UninstallJob &) const
- {
- return true;
- }
-
- bool visit(const ErrorJob &) const
- {
- return true;
- }
-
- bool visit(const UsableGroupJob &) const
- {
- return false;
- }
-
- bool visit(const UsableJob &) const
- {
- return true;
- }
-
- bool visit(const SimpleInstallJob &) const
- {
- return false;
- }
- };
-}
-
-const JobID
-Jobs::find_id_for_installed(const Resolvent & r) const
-{
- std::pair<JobsListByResolventIndex::const_iterator, JobsListByResolventIndex::const_iterator> candidates(
- _imp->jobs_list_by_resolvent_index.equal_range(r));
-
- for ( ; candidates.first != candidates.second ; ++candidates.first)
- {
- if ((*candidates.first->second)->accept_returning<bool>(InstalledJobChecker()))
- return (*candidates.first->second)->id();
- }
-
- return find_id_for_usable(r);
-}
-
-const JobID
-Jobs::find_id_for_usable(const Resolvent & r) const
-{
- std::pair<JobsListByResolventIndex::const_iterator, JobsListByResolventIndex::const_iterator> candidates(
- _imp->jobs_list_by_resolvent_index.equal_range(r));
-
- for ( ; candidates.first != candidates.second ; ++candidates.first)
- {
- if ((*candidates.first->second)->accept_returning<bool>(UsableJobChecker()))
- return (*candidates.first->second)->id();
- }
-
- throw InternalError(PALUDIS_HERE, "no build job for " + stringify(r));
-}
-
-bool
-Jobs::have_job_for_installed(const Resolvent & r) const
-{
- std::pair<JobsListByResolventIndex::const_iterator, JobsListByResolventIndex::const_iterator> candidates(
- _imp->jobs_list_by_resolvent_index.equal_range(r));
-
- for ( ; candidates.first != candidates.second ; ++candidates.first)
- {
- if ((*candidates.first->second)->accept_returning<bool>(InstalledJobChecker()))
- return true;
- }
-
- return have_job_for_usable(r);
-}
-
-bool
-Jobs::have_job_for_usable(const Resolvent & r) const
-{
- std::pair<JobsListByResolventIndex::const_iterator, JobsListByResolventIndex::const_iterator> candidates(
- _imp->jobs_list_by_resolvent_index.equal_range(r));
-
- for ( ; candidates.first != candidates.second ; ++candidates.first)
- {
- if ((*candidates.first->second)->accept_returning<bool>(UsableJobChecker()))
- return true;
- }
-
- return false;
-}
-
-const std::tr1::shared_ptr<Job>
-Jobs::fetch(const JobID & id)
-{
- JobsListByJobIDIndex::const_iterator i(_imp->jobs_list_by_job_id_index.find(id));
- if (i == _imp->jobs_list_by_job_id_index.end())
- throw InternalError(PALUDIS_HERE, "no job for id");
- return *i->second;
-}
-
-const std::tr1::shared_ptr<const Job>
-Jobs::fetch(const JobID & id) const
-{
- JobsListByJobIDIndex::const_iterator i(_imp->jobs_list_by_job_id_index.find(id));
- if (i == _imp->jobs_list_by_job_id_index.end())
- throw InternalError(PALUDIS_HERE, "no job for id");
- return *i->second;
-}
-
-template <typename J_>
-const std::tr1::shared_ptr<const J_>
-Jobs::fetch_as(const JobID & id) const
-{
- JobsListByJobIDIndex::const_iterator i(_imp->jobs_list_by_job_id_index.find(id));
- if (i == _imp->jobs_list_by_job_id_index.end())
- throw InternalError(PALUDIS_HERE, "no job for id");
- if (simple_visitor_cast<const J_>(**i->second))
- return std::tr1::static_pointer_cast<const J_>(*i->second);
- else
- throw InternalError(PALUDIS_HERE, "wrong job type id");
-}
-
-void
-Jobs::serialise(Serialiser & s) const
-{
- s.object("Jobs")
- .member(SerialiserFlags<serialise::container>(), "items", _imp->jobs)
- ;
-}
-
-const std::tr1::shared_ptr<Jobs>
-Jobs::deserialise(Deserialisation & d)
-{
- Deserialisator v(d, "Jobs");
- Deserialisator vv(*v.find_remove_member("items"), "c");
- std::tr1::shared_ptr<Jobs> result(new Jobs);
- for (int n(1), n_end(vv.member<int>("count") + 1) ; n != n_end ; ++n)
- result->add(vv.member<std::tr1::shared_ptr<Job> >(stringify(n)));
- return result;
-}
-
-template class PrivateImplementationPattern<resolver::Jobs>;
-
-template const std::tr1::shared_ptr<const SimpleInstallJob> Jobs::fetch_as<SimpleInstallJob>(const JobID &) const;
-template const std::tr1::shared_ptr<const ErrorJob> Jobs::fetch_as<ErrorJob>(const JobID &) const;
-template const std::tr1::shared_ptr<const FetchJob> Jobs::fetch_as<FetchJob>(const JobID &) const;
-template const std::tr1::shared_ptr<const UsableJob> Jobs::fetch_as<UsableJob>(const JobID &) const;
-
diff --git a/paludis/resolver/jobs.hh b/paludis/resolver/jobs.hh
deleted file mode 100644
index bdd9dfa..0000000
--- a/paludis/resolver/jobs.hh
+++ /dev/null
@@ -1,75 +0,0 @@
-/* vim: set sw=4 sts=4 et foldmethod=syntax : */
-
-/*
- * Copyright (c) 2009, 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_PALUDIS_RESOLVER_JOBS_HH
-#define PALUDIS_GUARD_PALUDIS_RESOLVER_JOBS_HH 1
-
-#include <paludis/resolver/jobs-fwd.hh>
-#include <paludis/resolver/job-fwd.hh>
-#include <paludis/resolver/job_id-fwd.hh>
-#include <paludis/resolver/resolvent-fwd.hh>
-#include <paludis/util/attributes.hh>
-#include <paludis/util/private_implementation_pattern.hh>
-#include <paludis/serialise-fwd.hh>
-#include <tr1/memory>
-
-namespace paludis
-{
- namespace resolver
- {
- class PALUDIS_VISIBLE Jobs :
- private PrivateImplementationPattern<Jobs>
- {
- public:
- Jobs();
- ~Jobs();
-
- void add(const std::tr1::shared_ptr<Job> &);
-
- bool have_job_for_installed(const Resolvent &) const PALUDIS_ATTRIBUTE((warn_unused_result));
-
- const JobID find_id_for_installed(const Resolvent &) const PALUDIS_ATTRIBUTE((warn_unused_result));
-
- bool have_job_for_usable(const Resolvent &) const PALUDIS_ATTRIBUTE((warn_unused_result));
-
- const JobID find_id_for_usable(const Resolvent &) const PALUDIS_ATTRIBUTE((warn_unused_result));
-
- const std::tr1::shared_ptr<Job> fetch(
- const JobID &) PALUDIS_ATTRIBUTE((warn_unused_result));
-
- const std::tr1::shared_ptr<const Job> fetch(
- const JobID &) const PALUDIS_ATTRIBUTE((warn_unused_result));
-
- template <typename J_>
- const std::tr1::shared_ptr<const J_> fetch_as(
- const JobID &) const PALUDIS_ATTRIBUTE((warn_unused_result));
-
- void serialise(Serialiser &) const;
-
- static const std::tr1::shared_ptr<Jobs> deserialise(
- Deserialisation & d) PALUDIS_ATTRIBUTE((warn_unused_result));
- };
- }
-
-#ifdef PALUDIS_HAVE_EXTERN_TEMPLATE
- extern template class PrivateImplementationPattern<resolver::Jobs>;
-#endif
-
-}
-#endif
diff --git a/paludis/resolver/failure_kinds.hh b/paludis/resolver/nag-fwd.hh
index 76a93cd..3ebc41e 100644
--- a/paludis/resolver/failure_kinds.hh
+++ b/paludis/resolver/nag-fwd.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009 Ciaran McCreesh
+ * 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
@@ -17,16 +17,15 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef PALUDIS_GUARD_PALUDIS_RESOLVER_FAILURE_KINDS_HH
-#define PALUDIS_GUARD_PALUDIS_RESOLVER_FAILURE_KINDS_HH 1
-
-#include <paludis/resolver/failure_kinds-fwd.hh>
+#ifndef PALUDIS_GUARD_PALUDIS_RESOLVER_NAG_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_RESOLVER_NAG_FWD_HH 1
namespace paludis
{
namespace resolver
{
-
+ struct NAG;
+ struct NAGEdgeProperties;
}
}
diff --git a/paludis/resolver/nag.cc b/paludis/resolver/nag.cc
new file mode 100644
index 0000000..0f887c8
--- /dev/null
+++ b/paludis/resolver/nag.cc
@@ -0,0 +1,370 @@
+/* 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 <paludis/resolver/nag.hh>
+#include <paludis/resolver/resolvent.hh>
+#include <paludis/resolver/strongly_connected_component.hh>
+#include <paludis/util/private_implementation_pattern-impl.hh>
+#include <paludis/util/hashes.hh>
+#include <paludis/util/exception.hh>
+#include <paludis/util/stringify.hh>
+#include <paludis/util/make_named_values.hh>
+#include <paludis/util/make_shared_ptr.hh>
+#include <paludis/util/wrapped_output_iterator.hh>
+#include <paludis/util/wrapped_forward_iterator-impl.hh>
+#include <paludis/util/sequence.hh>
+#include <paludis/util/member_iterator-impl.hh>
+#include <paludis/serialise-impl.hh>
+#include <tr1/unordered_set>
+#include <tr1/unordered_map>
+#include <algorithm>
+#include <list>
+#include <set>
+
+using namespace paludis;
+using namespace paludis::resolver;
+
+typedef std::tr1::unordered_set<Resolvent, Hash<Resolvent> > Nodes;
+typedef std::tr1::unordered_map<Resolvent, NAGEdgeProperties, Hash<Resolvent> > NodesWithProperties;
+typedef std::tr1::unordered_map<Resolvent, NodesWithProperties, Hash<Resolvent> > Edges;
+typedef std::tr1::unordered_map<Resolvent, Nodes, Hash<Resolvent> > PlainEdges;
+
+namespace paludis
+{
+ namespace n
+ {
+ typedef Name<struct index_name> index;
+ typedef Name<struct lowlink_name> lowlink;
+ }
+
+ template <>
+ struct Implementation<NAG>
+ {
+ Nodes nodes;
+ Edges edges;
+ const NodesWithProperties empty_nodes_with_properties;
+ };
+
+ template <>
+ struct WrappedForwardIteratorTraits<NAG::EdgesFromConstIteratorTag>
+ {
+ typedef NodesWithProperties::const_iterator UnderlyingIterator;
+ };
+
+ template <>
+ struct WrappedForwardIteratorTraits<NAG::NodesConstIteratorTag>
+ {
+ typedef Nodes::const_iterator UnderlyingIterator;
+ };
+}
+
+NAG::NAG() :
+ PrivateImplementationPattern<NAG>(new Implementation<NAG>)
+{
+}
+
+NAG::~NAG()
+{
+}
+
+void
+NAG::add_node(const Resolvent & r)
+{
+ _imp->nodes.insert(r);
+}
+
+void
+NAG::add_edge(const Resolvent & a, const Resolvent & b, const NAGEdgeProperties & p)
+{
+ _imp->edges.insert(std::make_pair(a, NodesWithProperties())).first->second.insert(std::make_pair(b, p)).first->second |= p;
+}
+
+void
+NAG::verify_edges() const
+{
+ for (Edges::const_iterator e(_imp->edges.begin()), e_end(_imp->edges.end()) ;
+ e != e_end ; ++e)
+ {
+ if (_imp->nodes.end() == _imp->nodes.find(e->first))
+ throw InternalError(PALUDIS_HERE, "Missing node for edge " + stringify(e->first));
+
+ for (NodesWithProperties::const_iterator f(e->second.begin()), f_end(e->second.end()) ;
+ f != f_end ; ++f)
+ if (_imp->nodes.end() == _imp->nodes.find(f->first))
+ throw InternalError(PALUDIS_HERE, "Missing node for edge " + stringify(e->first) + " -> " + stringify(f->first));
+ }
+}
+
+namespace
+{
+ struct TarjanData
+ {
+ NamedValue<n::index, int> index;
+ NamedValue<n::lowlink, int> lowlink;
+ };
+
+ typedef std::tr1::unordered_map<Resolvent, TarjanData, Hash<Resolvent> > TarjanDataMap;
+ typedef std::list<Resolvent> TarjanStack;
+ typedef std::tr1::unordered_map<Resolvent, StronglyConnectedComponent, Hash<Resolvent> > StronglyConnectedComponentsByRepresentative;
+ typedef std::tr1::unordered_map<Resolvent, Resolvent, Hash<Resolvent> > RepresentativeNodes;
+
+ TarjanDataMap::iterator tarjan(const Resolvent & node, const Edges & edges, TarjanDataMap & data, TarjanStack & stack, int & index,
+ StronglyConnectedComponentsByRepresentative & result)
+ {
+ TarjanDataMap::iterator node_data(data.insert(std::make_pair(node, make_named_values<TarjanData>(
+ n::index() = index,
+ n::lowlink() = index
+ ))).first);
+ ++index;
+
+ TarjanStack::iterator top_of_stack_before_node(stack.begin());
+ stack.push_front(node);
+
+ Edges::const_iterator e(edges.find(node));
+ if (e != edges.end())
+ {
+ for (NodesWithProperties::const_iterator n(e->second.begin()), n_end(e->second.end()) ;
+ n != n_end ; ++n)
+ {
+ TarjanDataMap::iterator n_data(data.find(n->first));
+ if (data.end() == n_data)
+ {
+ n_data = tarjan(n->first, edges, data, stack, index, result);
+ node_data->second.lowlink() = std::min(node_data->second.lowlink(), n_data->second.lowlink());
+ }
+ else if (stack.end() != std::find(stack.begin(), stack.end(), n->first))
+ node_data->second.lowlink() = std::min(node_data->second.lowlink(), n_data->second.index());
+ }
+ }
+
+ if (node_data->second.index() == node_data->second.lowlink())
+ {
+ StronglyConnectedComponent scc(make_named_values<StronglyConnectedComponent>(
+ n::nodes() = make_shared_ptr(new Set<Resolvent>),
+ n::requirements() = make_shared_ptr(new Set<Resolvent>)
+ ));
+
+ std::copy(stack.begin(), top_of_stack_before_node, scc.nodes()->inserter());
+ stack.erase(stack.begin(), top_of_stack_before_node);
+
+ if (scc.nodes()->empty())
+ throw InternalError(PALUDIS_HERE, "empty scc");
+ result.insert(std::make_pair(*scc.nodes()->begin(), scc));
+ }
+
+ return node_data;
+ }
+
+ void dfs(
+ const StronglyConnectedComponentsByRepresentative & sccs,
+ const Resolvent & node,
+ const PlainEdges & edges,
+ Nodes & done,
+ std::tr1::shared_ptr<SortedStronglyConnectedComponents> & result)
+ {
+ if (done.end() != done.find(node))
+ return;
+
+ PlainEdges::const_iterator e(edges.find(node));
+ std::set<Resolvent> consistently_ordered_edges;
+ if (e != edges.end())
+ std::copy(e->second.begin(), e->second.end(), std::inserter(consistently_ordered_edges, consistently_ordered_edges.begin()));
+
+ for (std::set<Resolvent>::const_iterator n(consistently_ordered_edges.begin()), n_end(consistently_ordered_edges.end()) ;
+ n != n_end ; ++n)
+ dfs(sccs, *n, edges, done, result);
+
+ done.insert(node);
+ result->push_back(sccs.find(node)->second);
+ }
+}
+
+const std::tr1::shared_ptr<const SortedStronglyConnectedComponents>
+NAG::sorted_strongly_connected_components() const
+{
+ StronglyConnectedComponentsByRepresentative sccs;
+ TarjanDataMap data;
+ TarjanStack stack;
+
+ /* find our strongly connected components */
+ int index(0);
+ for (Nodes::const_iterator n(_imp->nodes.begin()), n_end(_imp->nodes.end()) ;
+ n != n_end ; ++n)
+ if (data.end() == data.find(*n))
+ tarjan(*n, _imp->edges, data, stack, index, sccs);
+
+ /* find the 'representative' scc node for every node */
+ RepresentativeNodes representative_nodes;
+ for (StronglyConnectedComponentsByRepresentative::const_iterator s(sccs.begin()), s_end(sccs.end()) ;
+ s != s_end ; ++s)
+ for (Set<Resolvent>::ConstIterator r(s->second.nodes()->begin()), r_end(s->second.nodes()->end()) ;
+ r != r_end ; ++r)
+ if (! representative_nodes.insert(std::make_pair(*r, s->first)).second)
+ throw InternalError(PALUDIS_HERE, "node in multiple sccs");
+
+ /* sanity check, to avoid us much weirdness if there's a bug */
+ if (representative_nodes.size() != _imp->nodes.size())
+ throw InternalError(PALUDIS_HERE, "mismatch");
+
+ /* build edges between SCCs */
+ PlainEdges scc_edges;
+ for (Edges::const_iterator e(_imp->edges.begin()), e_end(_imp->edges.end()) ;
+ e != e_end ; ++e)
+ {
+ RepresentativeNodes::const_iterator from(representative_nodes.find(e->first));
+ for (NodesWithProperties::const_iterator n(e->second.begin()), n_end(e->second.end()) ;
+ n != n_end ; ++n)
+ {
+ RepresentativeNodes::const_iterator to(representative_nodes.find(n->first));
+ if (! (to->second == from->second))
+ scc_edges.insert(std::make_pair(from->second, Nodes())).first->second.insert(to->second);
+ }
+ }
+
+ /* topological sort with consistent ordering (mostly to make test cases
+ * easier). we know there're no cycles. */
+ std::tr1::shared_ptr<SortedStronglyConnectedComponents> result(new SortedStronglyConnectedComponents);
+ Nodes done;
+ std::set<Resolvent> consistently_ordered_representative_nodes;
+ std::copy(first_iterator(sccs.begin()), first_iterator(sccs.end()),
+ std::inserter(consistently_ordered_representative_nodes, consistently_ordered_representative_nodes.begin()));
+ for (std::set<Resolvent>::const_iterator n(consistently_ordered_representative_nodes.begin()),
+ n_end(consistently_ordered_representative_nodes.end()) ;
+ n != n_end ; ++n)
+ dfs(sccs, *n, scc_edges, done, result);
+
+ if (done.size() != sccs.size())
+ throw InternalError(PALUDIS_HERE, "mismatch");
+
+ return result;
+}
+
+NAG::EdgesFromConstIterator
+NAG::begin_edges_from(const Resolvent & r) const
+{
+ Edges::const_iterator e(_imp->edges.find(r));
+ if (e == _imp->edges.end())
+ return EdgesFromConstIterator(_imp->empty_nodes_with_properties.end());
+ else
+ return EdgesFromConstIterator(e->second.begin());
+}
+
+NAG::EdgesFromConstIterator
+NAG::end_edges_from(const Resolvent & r) const
+{
+ Edges::const_iterator e(_imp->edges.find(r));
+ if (e == _imp->edges.end())
+ return EdgesFromConstIterator(_imp->empty_nodes_with_properties.end());
+ else
+ return EdgesFromConstIterator(e->second.end());
+}
+
+NAG::NodesConstIterator
+NAG::begin_nodes() const
+{
+ return NodesConstIterator(_imp->nodes.begin());
+}
+
+NAG::NodesConstIterator
+NAG::end_nodes() const
+{
+ return NodesConstIterator(_imp->nodes.end());
+}
+
+void
+NAG::serialise(Serialiser & s) const
+{
+ SerialiserObjectWriter w(s.object("NAG"));
+ w.member(SerialiserFlags<serialise::container>(), "nodes", _imp->nodes);
+
+ int c(0);
+ for (Edges::const_iterator e(_imp->edges.begin()), e_end(_imp->edges.end()) ;
+ e != e_end ; ++e)
+ {
+ for (NodesWithProperties::const_iterator n(e->second.begin()), n_end(e->second.end()) ;
+ n != n_end ; ++n)
+ {
+ ++c;
+ w.member(SerialiserFlags<>(), "edge." + stringify(c) + ".f", e->first);
+ w.member(SerialiserFlags<>(), "edge." + stringify(c) + ".t", n->first);
+ w.member(SerialiserFlags<>(), "edge." + stringify(c) + ".p", n->second);
+ }
+ }
+
+ w.member(SerialiserFlags<>(), "edge.count", stringify(c));
+}
+
+const std::tr1::shared_ptr<NAG>
+NAG::deserialise(Deserialisation & d)
+{
+ Deserialisator v(d, "NAG");
+ std::tr1::shared_ptr<NAG> result(new NAG);
+
+ {
+ Deserialisator vv(*v.find_remove_member("nodes"), "c");
+ for (int n(1), n_end(vv.member<int>("count") + 1) ; n != n_end ; ++n)
+ result->add_node(vv.member<Resolvent>(stringify(n)));
+ }
+
+ for (int n(1), n_end(v.member<int>("edge.count") + 1) ; n != n_end ; ++n)
+ result->add_edge(
+ v.member<Resolvent>("edge." + stringify(n) + ".f"),
+ v.member<Resolvent>("edge." + stringify(n) + ".t"),
+ v.member<NAGEdgeProperties>("edge." + stringify(n) + ".p")
+ );
+
+ result->verify_edges();
+ return result;
+}
+
+NAGEdgeProperties &
+NAGEdgeProperties::operator|= (const NAGEdgeProperties & other)
+{
+ build() |= other.build();
+ run() |= other.run();
+ return *this;
+}
+
+void
+NAGEdgeProperties::serialise(Serialiser & s) const
+{
+ s.object("NAGEdgeProperties")
+ .member(SerialiserFlags<>(), "build", build())
+ .member(SerialiserFlags<>(), "build_all_met", build_all_met())
+ .member(SerialiserFlags<>(), "run", run())
+ .member(SerialiserFlags<>(), "run_all_met", run_all_met())
+ ;
+}
+
+const NAGEdgeProperties
+NAGEdgeProperties::deserialise(Deserialisation & d)
+{
+ Deserialisator v(d, "NAGEdgeProperties");
+
+ return make_named_values<NAGEdgeProperties>(
+ n::build() = v.member<bool>("build"),
+ n::build_all_met() = v.member<bool>("build_all_met"),
+ n::run() = v.member<bool>("run"),
+ n::run_all_met() = v.member<bool>("run_all_met")
+ );
+}
+
+template class WrappedForwardIterator<NAG::EdgesFromConstIteratorTag, const std::pair<const Resolvent, NAGEdgeProperties> >;
+template class WrappedForwardIterator<NAG::NodesConstIteratorTag, const Resolvent>;
+
diff --git a/paludis/resolver/nag.hh b/paludis/resolver/nag.hh
new file mode 100644
index 0000000..4f400bb
--- /dev/null
+++ b/paludis/resolver/nag.hh
@@ -0,0 +1,94 @@
+/* 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_PALUDIS_RESOLVER_NAG_HH
+#define PALUDIS_GUARD_PALUDIS_RESOLVER_NAG_HH 1
+
+#include <paludis/resolver/nag-fwd.hh>
+#include <paludis/resolver/resolvent-fwd.hh>
+#include <paludis/resolver/strongly_connected_component-fwd.hh>
+#include <paludis/util/private_implementation_pattern.hh>
+#include <paludis/util/wrapped_forward_iterator.hh>
+#include <paludis/util/named_value.hh>
+#include <paludis/serialise-fwd.hh>
+#include <tr1/memory>
+
+namespace paludis
+{
+ namespace n
+ {
+ typedef Name<struct build_name> build;
+ typedef Name<struct build_all_met_name> build_all_met;
+ typedef Name<struct run_name> run;
+ typedef Name<struct run_all_met_name> run_all_met;
+ }
+
+ namespace resolver
+ {
+ struct NAGEdgeProperties
+ {
+ NamedValue<n::build, bool> build;
+ NamedValue<n::build_all_met, bool> build_all_met;
+ NamedValue<n::run, bool> run;
+ NamedValue<n::run_all_met, bool> run_all_met;
+
+ NAGEdgeProperties & operator|= (const NAGEdgeProperties &);
+
+ void serialise(Serialiser &) const;
+ static const NAGEdgeProperties deserialise(Deserialisation & d) PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
+
+ class NAG :
+ private PrivateImplementationPattern<NAG>
+ {
+ public:
+ NAG();
+ ~NAG();
+
+ void add_node(const Resolvent &);
+ void add_edge(const Resolvent &, const Resolvent &, const NAGEdgeProperties &);
+
+ void verify_edges() const;
+
+ const std::tr1::shared_ptr<const SortedStronglyConnectedComponents>
+ sorted_strongly_connected_components() const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ struct EdgesFromConstIteratorTag;
+ typedef WrappedForwardIterator<EdgesFromConstIteratorTag, const std::pair<const Resolvent, NAGEdgeProperties> > EdgesFromConstIterator;
+ EdgesFromConstIterator begin_edges_from(const Resolvent &) const PALUDIS_ATTRIBUTE((warn_unused_result));
+ EdgesFromConstIterator end_edges_from(const Resolvent &) const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ struct NodesConstIteratorTag;
+ typedef WrappedForwardIterator<NodesConstIteratorTag, const Resolvent> NodesConstIterator;
+ NodesConstIterator begin_nodes() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ NodesConstIterator end_nodes() const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ void serialise(Serialiser &) const;
+ static const std::tr1::shared_ptr<NAG> deserialise(Deserialisation & d) PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
+ }
+
+#ifdef PALUDIS_HAVE_EXTERN_TEMPLATE
+ extern template class WrappedForwardIterator<resolver::NAG::EdgesFromConstIteratorTag,
+ const std::pair<const resolver::Resolvent, resolver::NAGEdgeProperties> >;
+ extern template class WrappedForwardIterator<resolver::NAG::NodesConstIteratorTag, const resolver::Resolvent>;
+#endif
+}
+
+#endif
diff --git a/paludis/resolver/orderer-fwd.hh b/paludis/resolver/orderer-fwd.hh
index 77cfbc5..37326bd 100644
--- a/paludis/resolver/orderer-fwd.hh
+++ b/paludis/resolver/orderer-fwd.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009 Ciaran McCreesh
+ * 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
@@ -17,8 +17,8 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef PALUDIS_GUARD_PALUDIS_RESOLVER_ORDERER_FWD_HH
-#define PALUDIS_GUARD_PALUDIS_RESOLVER_ORDERER_FWD_HH 1
+#ifndef PALUDIS_GUARD_PALUDIS_RESOLVER_LINEARISER_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_RESOLVER_LINEARISER_FWD_HH 1
namespace paludis
{
diff --git a/paludis/resolver/orderer.cc b/paludis/resolver/orderer.cc
index 4af4da9..b533b7d 100644
--- a/paludis/resolver/orderer.cc
+++ b/paludis/resolver/orderer.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009, 2010 Ciaran McCreesh
+ * 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
@@ -18,44 +18,40 @@
*/
#include <paludis/resolver/orderer.hh>
+#include <paludis/resolver/decision.hh>
+#include <paludis/resolver/decisions.hh>
+#include <paludis/resolver/resolution.hh>
+#include <paludis/resolver/nag.hh>
#include <paludis/resolver/reason.hh>
#include <paludis/resolver/constraint.hh>
-#include <paludis/resolver/resolvent.hh>
-#include <paludis/resolver/decider.hh>
-#include <paludis/resolver/resolution.hh>
-#include <paludis/resolver/arrow.hh>
-#include <paludis/resolver/decision.hh>
-#include <paludis/resolver/resolutions.hh>
-#include <paludis/resolver/resolver.hh>
-#include <paludis/resolver/resolver_lists.hh>
+#include <paludis/resolver/strongly_connected_component.hh>
+#include <paludis/resolver/resolutions_by_resolvent.hh>
+#include <paludis/resolver/job_lists.hh>
+#include <paludis/resolver/job_list.hh>
#include <paludis/resolver/job.hh>
-#include <paludis/resolver/jobs.hh>
-#include <paludis/resolver/required_confirmations.hh>
-#include <paludis/resolver/resolver_functions.hh>
+#include <paludis/resolver/job_requirements.hh>
+#include <paludis/resolver/destination.hh>
+#include <paludis/resolver/orderer_notes.hh>
+#include <paludis/util/private_implementation_pattern-impl.hh>
#include <paludis/util/exception.hh>
-#include <paludis/util/sequence-impl.hh>
-#include <paludis/util/wrapped_forward_iterator-impl.hh>
-#include <paludis/util/indirect_iterator-impl.hh>
-#include <paludis/util/accept_visitor.hh>
+#include <paludis/util/stringify.hh>
+#include <paludis/util/hashes.hh>
+#include <paludis/util/join.hh>
#include <paludis/util/make_named_values.hh>
#include <paludis/util/make_shared_ptr.hh>
-#include <paludis/util/stringify.hh>
-#include <paludis/util/private_implementation_pattern-impl.hh>
-#include <paludis/util/log.hh>
+#include <paludis/util/make_shared_copy.hh>
#include <paludis/util/simple_visitor_cast.hh>
-#include <paludis/match_package.hh>
-#include <paludis/generator.hh>
-#include <paludis/filter.hh>
-#include <paludis/filtered_generator.hh>
-#include <paludis/selection.hh>
+#include <paludis/environment.hh>
#include <paludis/notifier_callback.hh>
-#include <algorithm>
-#include <set>
+#include <tr1/unordered_set>
+#include <tr1/unordered_map>
+#include <list>
using namespace paludis;
using namespace paludis::resolver;
-typedef std::set<JobID> ToOrder;
+typedef std::tr1::unordered_map<Resolvent, std::tr1::shared_ptr<const ChangeOrRemoveDecision>, Hash<Resolvent> > ChangeOrRemoveResolvents;
+typedef std::tr1::unordered_map<Resolvent, JobNumber, Hash<Resolvent> > InstallJobNumbers;
namespace paludis
{
@@ -63,31 +59,24 @@ namespace paludis
struct Implementation<Orderer>
{
const Environment * const env;
- const ResolverFunctions fns;
- const std::tr1::shared_ptr<const Decider> decider;
-
- const std::tr1::shared_ptr<ResolverLists> lists;
+ const std::tr1::shared_ptr<Resolved> resolved;
+ ChangeOrRemoveResolvents change_or_remove_resolvents;
+ InstallJobNumbers install_job_numbers;
- ToOrder to_order;
-
- Implementation(const Environment * const e,
- const ResolverFunctions & f,
- const std::tr1::shared_ptr<const Decider> & d,
- const std::tr1::shared_ptr<ResolverLists> & l) :
+ Implementation(
+ const Environment * const e,
+ const std::tr1::shared_ptr<Resolved> & r) :
env(e),
- fns(f),
- decider(d),
- lists(l)
+ resolved(r)
{
}
};
}
-Orderer::Orderer(const Environment * const e,
- const ResolverFunctions & f,
- const std::tr1::shared_ptr<const Decider> & d,
- const std::tr1::shared_ptr<ResolverLists> & l) :
- PrivateImplementationPattern<Orderer>(new Implementation<Orderer>(e, f, d, l))
+Orderer::Orderer(
+ const Environment * const e,
+ const std::tr1::shared_ptr<Resolved> & r) :
+ PrivateImplementationPattern<Orderer>(new Implementation<Orderer>(e, r))
{
}
@@ -95,232 +84,96 @@ Orderer::~Orderer()
{
}
-void
-Orderer::resolve()
-{
- _imp->env->trigger_notifier_callback(NotifierCallbackResolverStageEvent("Building Jobs"));
- _resolve_jobs();
- _imp->env->trigger_notifier_callback(NotifierCallbackResolverStageEvent("Building Arrows"));
- _resolve_jobs_dep_arrows();
- _imp->env->trigger_notifier_callback(NotifierCallbackResolverStageEvent("Ordering"));
- _resolve_order();
-}
-
-namespace paludis
-{
- namespace n
- {
- struct done_installs;
- struct done_pretends;
- }
-}
-
namespace
{
- struct DecisionHandler
+ typedef std::tr1::unordered_set<Resolvent, Hash<Resolvent> > ResolventsSet;
+
+ struct DecisionDispatcher
{
- typedef std::tr1::function<void (
- const std::tr1::shared_ptr<const Resolution> &,
- const ChangesToMakeDecision &,
- const std::tr1::shared_ptr<SimpleInstallJob> &)> MightNeedConfirmationFunction;
-
- const std::tr1::shared_ptr<Resolution> resolution;
- const std::tr1::shared_ptr<ResolverLists> lists;
- ToOrder & to_order;
- MightNeedConfirmationFunction might_need_confirmation;
-
- DecisionHandler(
- const std::tr1::shared_ptr<Resolution> & r,
- const std::tr1::shared_ptr<ResolverLists> & l,
- ToOrder & o,
- const MightNeedConfirmationFunction & m) :
- resolution(r),
- lists(l),
- to_order(o),
- might_need_confirmation(m)
- {
- }
+ const std::tr1::shared_ptr<Resolved> resolved;
+ ResolventsSet & ignore_dependencies_from_resolvents;
+ ChangeOrRemoveResolvents & change_or_remove_resolvents;
+ const Resolvent resolvent;
+ const std::tr1::shared_ptr<const Decision> decision;
+
+ DecisionDispatcher(
+ const std::tr1::shared_ptr<Resolved> & r,
+ ResolventsSet & i,
+ ChangeOrRemoveResolvents & c,
+ const Resolvent & v,
+ const std::tr1::shared_ptr<const Decision> & d) :
+ resolved(r),
+ ignore_dependencies_from_resolvents(i),
+ change_or_remove_resolvents(c),
+ resolvent(v),
+ decision(d)
+ {
+ }
+
+ bool visit(const UnableToMakeDecision &)
+ {
+ if (decision->taken())
+ resolved->taken_unable_to_make_decisions()->cast_push_back(decision);
+ else
+ resolved->untaken_unable_to_make_decisions()->cast_push_back(decision);
- void visit(const NothingNoChangeDecision & d)
- {
- if (d.taken())
- {
- Log::get_instance()->message("resolver.orderer.job.nothing_no_change", ll_debug, lc_no_context)
- << "taken " << resolution->resolvent() << " nothing no change";
+ ignore_dependencies_from_resolvents.insert(resolvent);
- const std::tr1::shared_ptr<UsableJob> usable_job(new UsableJob(resolution));
- lists->jobs()->add(usable_job);
- to_order.insert(usable_job->id());
- }
- else
- {
- Log::get_instance()->message("resolver.orderer.job.nothing_no_change", ll_debug, lc_no_context)
- << "untaken " << resolution->resolvent() << " nothing no change";
- }
+ return false;
}
- void visit(const ExistingNoChangeDecision & d)
+ bool visit(const NothingNoChangeDecision &)
{
- if (d.taken())
- {
- Log::get_instance()->message("resolver.orderer.job.existing_no_change", ll_debug, lc_no_context)
- << "taken " << resolution->resolvent() << " existing no change";
-
- const std::tr1::shared_ptr<UsableJob> usable_job(new UsableJob(resolution));
- lists->jobs()->add(usable_job);
- to_order.insert(usable_job->id());
- }
- else
- {
- Log::get_instance()->message("resolver.orderer.job.existing_no_change", ll_debug, lc_no_context)
- << "untaken " << resolution->resolvent() << " existing no change";
- }
+ resolved->nag()->add_node(resolvent);
+ return true;
}
- void visit(const ChangesToMakeDecision & d)
+ bool visit(const ExistingNoChangeDecision &)
{
- if (d.taken())
- {
- Log::get_instance()->message("resolver.orderer.job.changes_to_make", ll_debug, lc_no_context)
- << "taken " << resolution->resolvent() << " changes to make";
-
- const std::tr1::shared_ptr<FetchJob> fetch_job(new FetchJob(resolution,
- d.shared_from_this()));
- lists->jobs()->add(fetch_job);
- to_order.insert(fetch_job->id());
-
- const std::tr1::shared_ptr<SimpleInstallJob> install_job(new SimpleInstallJob(resolution,
- d.shared_from_this()));
- lists->jobs()->add(install_job);
- to_order.insert(install_job->id());
-
- const std::tr1::shared_ptr<UsableJob> usable_job(new UsableJob(resolution));
- lists->jobs()->add(usable_job);
- to_order.insert(usable_job->id());
-
- /* we can't install until we've fetched */
- install_job->arrows()->push_back(make_named_values<Arrow>(
- n::comes_after() = fetch_job->id(),
- n::failure_kinds() = FailureKinds(),
- n::maybe_reason() = make_null_shared_ptr()
- ));
-
- /* we aren't usable until we've been installed */
- usable_job->arrows()->push_back(make_named_values<Arrow>(
- n::comes_after() = install_job->id(),
- n::failure_kinds() = FailureKinds(),
- n::maybe_reason() = make_null_shared_ptr()
- ));
-
- /* do we need confirmation of this? */
- might_need_confirmation(resolution, d, install_job);
- }
- else
- {
- Log::get_instance()->message("resolver.orderer.job.changes_to_make", ll_debug, lc_no_context)
- << "untaken " << resolution->resolvent() << " changes to make";
-
- const std::tr1::shared_ptr<SimpleInstallJob> install_job(new SimpleInstallJob(resolution, d.shared_from_this()));
- lists->jobs()->add(install_job);
- lists->untaken_job_ids()->push_back(install_job->id());
- }
+ resolved->nag()->add_node(resolvent);
+ return true;
}
- void visit(const UnableToMakeDecision & d)
+ bool visit(const ChangesToMakeDecision &)
{
- if (d.taken())
+ if (decision->taken())
{
- Log::get_instance()->message("resolver.orderer.job.unable_to_make", ll_debug, lc_no_context)
- << "taken " << resolution->resolvent() << " unable to make";
-
- const std::tr1::shared_ptr<ErrorJob> error_job(new ErrorJob(resolution, d.shared_from_this()));
- lists->jobs()->add(error_job);
- lists->taken_error_job_ids()->push_back(error_job->id());
+ resolved->nag()->add_node(resolvent);
+ change_or_remove_resolvents.insert(std::make_pair(resolvent,
+ std::tr1::static_pointer_cast<const ChangeOrRemoveDecision>(decision)));
+ return true;
}
else
{
- Log::get_instance()->message("resolver.orderer.job.unable_to_make", ll_debug, lc_no_context)
- << "untaken " << resolution->resolvent() << " unable to make";
-
- const std::tr1::shared_ptr<ErrorJob> error_job(new ErrorJob(resolution, d.shared_from_this()));
- lists->jobs()->add(error_job);
- lists->untaken_error_job_ids()->push_back(error_job->id());
+ resolved->untaken_change_or_remove_decisions()->cast_push_back(decision);
+ return false;
}
}
- void visit(const RemoveDecision & d)
+ bool visit(const RemoveDecision &)
{
- if (d.taken())
+ if (decision->taken())
{
- Log::get_instance()->message("resolver.orderer.job.remove_decision", ll_debug, lc_no_context)
- << "taken " << resolution->resolvent() << " remove decision";
-
- const std::tr1::shared_ptr<UninstallJob> uninstall_job(new UninstallJob(resolution,
- d.shared_from_this()));
- lists->jobs()->add(uninstall_job);
- to_order.insert(uninstall_job->id());
+ resolved->nag()->add_node(resolvent);
+ change_or_remove_resolvents.insert(std::make_pair(resolvent,
+ std::tr1::static_pointer_cast<const ChangeOrRemoveDecision>(decision)));
+ return true;
}
else
- {
- Log::get_instance()->message("resolver.orderer.job.remove_decision", ll_debug, lc_no_context)
- << "untaken " << resolution->resolvent() << " remove decision";
-
- const std::tr1::shared_ptr<UninstallJob> uninstall_job(new UninstallJob(resolution, d.shared_from_this()));
- lists->jobs()->add(uninstall_job);
- lists->untaken_job_ids()->push_back(uninstall_job->id());
- }
+ throw InternalError(PALUDIS_HERE, "untaken RemoveDecision");
}
};
-}
-
-void
-Orderer::_resolve_jobs()
-{
- for (Resolutions::ConstIterator i(_imp->lists->all_resolutions()->begin()),
- i_end(_imp->lists->all_resolutions()->end()) ;
- i != i_end ; ++i)
- {
- DecisionHandler d(*i, _imp->lists, _imp->to_order, std::tr1::bind(
- &Orderer::_confirm, this, std::tr1::placeholders::_1,
- std::tr1::placeholders::_2, std::tr1::placeholders::_3));
- (*i)->decision()->accept(d);
- }
-}
-
-void
-Orderer::_confirm(
- const std::tr1::shared_ptr<const Resolution> & resolution,
- const ChangesToMakeDecision & decision,
- const std::tr1::shared_ptr<SimpleInstallJob> & job)
-{
- if (! decision.best())
- {
- const std::tr1::shared_ptr<RequiredConfirmation> c(new NotBestConfirmation);
- if (! _imp->fns.confirm_fn()(resolution->resolvent(), resolution, c))
- job->required_confirmations()->push_back(c);
- }
-
- if (ct_downgrade == decision.change_type())
- {
- const std::tr1::shared_ptr<DowngradeConfirmation> c(new DowngradeConfirmation);
- if (! _imp->fns.confirm_fn()(resolution->resolvent(), resolution, c))
- job->required_confirmations()->push_back(c);
- }
-
- if (! job->required_confirmations()->empty())
- _imp->lists->job_ids_needing_confirmation()->push_back(job->id());
-}
-namespace
-{
- struct LabelArrowsInfo
+ struct LabelsClassifier
{
bool build;
bool run;
+ bool post;
- LabelArrowsInfo() :
+ LabelsClassifier() :
build(false),
- run(false)
+ run(false),
+ post(false)
{
}
@@ -351,14 +204,17 @@ namespace
void visit(const DependenciesPostLabel &)
{
+ post = true;
}
void visit(const DependenciesSuggestionLabel &)
{
+ post = true;
}
void visit(const DependenciesRecommendationLabel &)
{
+ post = true;
}
void visit(const DependenciesCompileAgainstLabel &)
@@ -367,421 +223,374 @@ namespace
}
};
- struct DepArrowsAdder
+ struct EdgesFromReasonVisitor
{
- const std::tr1::shared_ptr<Jobs> jobs;
- const JobID our_identifier;
- const bool is_usable;
- const std::tr1::shared_ptr<const Reason> reason;
-
- DepArrowsAdder(
- const std::tr1::shared_ptr<Jobs> & j,
- const JobID & i,
- const bool u,
- const std::tr1::shared_ptr<const Reason> & r) :
- jobs(j),
- our_identifier(i),
- is_usable(u),
- reason(r)
- {
- }
-
- void visit(const TargetReason &) const
- {
- }
-
- void visit(const PresetReason &) const
- {
- }
+ const std::tr1::shared_ptr<NAG> nag;
+ const ResolventsSet & ignore_dependencies_from_resolvents;
+ const Resolvent resolvent;
- void visit(const SetReason & r) const
+ EdgesFromReasonVisitor(
+ const std::tr1::shared_ptr<NAG> & n,
+ const ResolventsSet & i,
+ const Resolvent & v) :
+ nag(n),
+ ignore_dependencies_from_resolvents(i),
+ resolvent(v)
{
- r.reason_for_set()->accept(*this);
}
- void visit(const DependencyReason & r) const
+ void visit(const DependencyReason & r)
{
- Context context("When adding arrows for job '" + stringify(our_identifier.string_id())
- + "' with reason '" + stringify(r.sanitised_dependency().spec())
- + "' from '" + stringify(r.from_resolvent()) + "':");
+ /* we may be constrained by a dep from a package that was changed
+ * from a non error decision to an unable to make decision */
+ if (ignore_dependencies_from_resolvents.end() != ignore_dependencies_from_resolvents.find(r.from_resolvent()))
+ return;
- FailureKinds failure_kinds;
- if (r.already_met())
- failure_kinds += fk_ignorable_if_satisfied;
+ /* what sort of dep are we? */
+ LabelsClassifier classifier;
+ for (DependenciesLabelSequence::ConstIterator l(r.sanitised_dependency().active_dependency_labels()->begin()),
+ l_end(r.sanitised_dependency().active_dependency_labels()->end()) ;
+ l != l_end ; ++l)
+ (*l)->accept(classifier);
- if (r.sanitised_dependency().spec().if_block())
+ if (classifier.build || classifier.run)
{
- /* only strong blockers impose arrows. todo: maybe weak
- * blockers should impose some kind of weak arrow? or would
- * that make matters worse with silly Gentoo KDE blockers? */
- if (r.sanitised_dependency().spec().if_block()->strong())
- {
- /* we might not be changing anything (e.g. for a blocker), or we
- * might be a dependency that got cancelled out later when
- * something was changed from a decision to an error. */
- if (! jobs->have_job_for_installed(r.from_resolvent()))
- {
- Log::get_instance()->message("resolver.orderer.job.no_job_for_installed", ll_warning, lc_context)
- << "No job for building '" << r.from_resolvent() << "'. Verify manually that this is sane for now.";
- return;
- }
-
- /* todo: this should probably only cause an arrow if the
- * blocker is currently met */
- jobs->fetch(jobs->find_id_for_installed(r.from_resolvent()))->arrows()->push_back(
- make_named_values<Arrow>(
- n::comes_after() = our_identifier,
- n::failure_kinds() = failure_kinds,
- n::maybe_reason() = reason
+ bool arrow(true);
+ if (r.sanitised_dependency().spec().if_block())
+ if (! r.sanitised_dependency().spec().if_block()->strong())
+ arrow = false;
+
+ if (arrow)
+ nag->add_edge(r.from_resolvent(), resolvent, make_named_values<NAGEdgeProperties>(
+ n::build() = classifier.build,
+ n::build_all_met() = r.already_met() || ! classifier.build,
+ n::run() = classifier.run,
+ n::run_all_met() = r.already_met() || ! classifier.run
));
- }
}
- else
+ else if (classifier.post)
{
- LabelArrowsInfo v;
- for (DependenciesLabelSequence::ConstIterator l(r.sanitised_dependency().active_dependency_labels()->begin()),
- l_end(r.sanitised_dependency().active_dependency_labels()->end()) ;
- l != l_end ; ++l)
- (*l)->accept(v);
-
- if (v.build || v.run)
- {
- /* we might not be changing anything (e.g. for a blocker), or we
- * might be a dependency that got cancelled out later when
- * something was changed from a decision to an error. */
- if (! jobs->have_job_for_usable(r.from_resolvent()))
- {
- Log::get_instance()->message("resolver.orderer.job.no_job_for_usable", ll_warning, lc_context)
- << "No job for building '" << r.from_resolvent() << "'. Verify manually that this is sane for now.";
- return;
- }
-
- if (v.build)
- {
- /* build: we must be usable before the other package is built */
- if (is_usable)
- jobs->fetch(jobs->find_id_for_installed(r.from_resolvent()))->arrows()->push_back(
- make_named_values<Arrow>(
- n::comes_after() = our_identifier,
- n::failure_kinds() = failure_kinds,
- n::maybe_reason() = reason
- ));
- }
-
- if (v.run)
- {
- /* run: we must be usable before the other package is usable */
- if (is_usable)
- jobs->fetch(jobs->find_id_for_usable(r.from_resolvent()))->arrows()->push_back(
- make_named_values<Arrow>(
- n::comes_after() = our_identifier,
- n::failure_kinds() = failure_kinds,
- n::maybe_reason() = reason
- ));
- }
- }
+ /* we won't add a backwards edge, since most post deps dep upon
+ * the thing requiring them anyway */
+ // nag->add_edge(resolvent, r.from_resolvent());
}
+ else
+ throw InternalError(PALUDIS_HERE, "No classification");
}
- void visit(const DependentReason &) const
- {
- }
- };
-
- struct DepArrowHandler
- {
- const std::tr1::shared_ptr<Jobs> jobs;
- const JobID our_identifier;
-
- DepArrowHandler(
- const std::tr1::shared_ptr<Jobs> & j,
- const JobID & i) :
- jobs(j),
- our_identifier(i)
- {
- }
-
- void add_dep_arrows(const bool u, const std::tr1::shared_ptr<const Resolution> & r)
- {
- for (Constraints::ConstIterator c(r->constraints()->begin()), c_end(r->constraints()->end()) ;
- c != c_end ; ++c)
- if ((*c)->reason())
- (*c)->reason()->accept(DepArrowsAdder(jobs, our_identifier, u, (*c)->reason()));
- }
-
- void visit(const SimpleInstallJob & c)
- {
- add_dep_arrows(false, c.resolution());
- }
-
- void visit(const UsableJob & c)
- {
- add_dep_arrows(true, c.resolution());
- }
-
- void visit(const UninstallJob &)
+ void visit(const SetReason & r)
{
+ if (r.reason_for_set())
+ r.reason_for_set()->accept(*this);
}
- void visit(const UsableGroupJob &)
+ void visit(const PresetReason &)
{
}
- void visit(const FetchJob &)
+ void visit(const DependentReason &)
{
}
- void visit(const ErrorJob &)
+ void visit(const TargetReason &)
{
}
};
-}
-
-void
-Orderer::_resolve_jobs_dep_arrows()
-{
- Context context("When resolving dep arrows:");
- for (ToOrder::const_iterator i(_imp->to_order.begin()),
- i_end(_imp->to_order.end()) ;
- i != i_end ; ++i)
+ bool no_build_dependencies(
+ const Set<Resolvent> & resolvents,
+ const NAG & nag)
{
- DepArrowHandler d(_imp->lists->jobs(), *i);
- _imp->lists->jobs()->fetch(*i)->accept(d);
+ for (Set<Resolvent>::ConstIterator r(resolvents.begin()), r_end(resolvents.end()) ;
+ r != r_end ; ++r)
+ for (NAG::EdgesFromConstIterator e(nag.begin_edges_from(*r)), e_end(nag.end_edges_from(*r)) ;
+ e != e_end ; ++e)
+ if (e->second.build())
+ return false;
+
+ return true;
}
}
void
-Orderer::_resolve_order()
+Orderer::resolve()
{
- while (true)
- {
- _imp->env->trigger_notifier_callback(NotifierCallbackResolverStageEvent("Ordering"));
-
- /* anything left? */
- if (_imp->to_order.empty())
- break;
-
- /* first attempt: nothing fancy */
- if (_order_some(false, false))
- continue;
-
- _imp->env->trigger_notifier_callback(NotifierCallbackResolverStageEvent("Ordering Usable Cycles"));
-
- /* second attempt: remove cycles containing only usable jobs */
- if (_remove_usable_cycles())
- continue;
-
- _imp->env->trigger_notifier_callback(NotifierCallbackResolverStageEvent("Ordering Using Existing"));
-
- /* third attempt: remove an install job whose deps are already met */
- if (_order_some(true, true))
- continue;
-
- _imp->env->trigger_notifier_callback(NotifierCallbackResolverStageEvent("Ordering Using Any Existing"));
+ _imp->env->trigger_notifier_callback(NotifierCallbackResolverStageEvent("Nodifying Decisions"));
- if (_order_some(true, false))
- continue;
-
- _cycle_error();
+ ResolventsSet ignore_dependencies_from_resolvents, ignore_edges_from_resolvents;
+ for (ResolutionsByResolvent::ConstIterator r(_imp->resolved->resolutions_by_resolvent()->begin()),
+ r_end(_imp->resolved->resolutions_by_resolvent()->end()) ;
+ r != r_end ; ++r)
+ {
+ DecisionDispatcher decision_dispatcher(
+ _imp->resolved,
+ ignore_dependencies_from_resolvents,
+ _imp->change_or_remove_resolvents,
+ (*r)->resolvent(),
+ (*r)->decision());
+ if (! (*r)->decision()->accept_returning<bool>(decision_dispatcher))
+ ignore_edges_from_resolvents.insert((*r)->resolvent());
}
-}
-bool
-Orderer::_order_some(const bool desperate, const bool installs_only)
-{
- bool result(false);
+ _imp->env->trigger_notifier_callback(NotifierCallbackResolverStageEvent("Building NAG Edges"));
- for (ToOrder::iterator i(_imp->to_order.begin()), i_next(i), i_end(_imp->to_order.end()) ;
- i != i_end ; i = i_next)
+ for (ResolutionsByResolvent::ConstIterator r(_imp->resolved->resolutions_by_resolvent()->begin()),
+ r_end(_imp->resolved->resolutions_by_resolvent()->end()) ;
+ r != r_end ; ++r)
{
- /* i might end up invalidated by the time we're done */
- JobID id(*i);
- ++i_next;
-
- if (installs_only)
- {
- const std::tr1::shared_ptr<const Job> job(_imp->lists->jobs()->fetch(*i));
- if (! simple_visitor_cast<const SimpleInstallJob>(*job))
- continue;
- }
-
- if (! _can_order(id, desperate))
+ if (ignore_dependencies_from_resolvents.end() != ignore_edges_from_resolvents.find((*r)->resolvent()))
continue;
- if (desperate)
- {
- const std::tr1::shared_ptr<Job> job(_imp->lists->jobs()->fetch(id));
- for (ArrowSequence::ConstIterator a(job->arrows()->begin()), a_end(job->arrows()->end()) ;
- a != a_end ; ++a)
- if (_imp->to_order.end() != _imp->to_order.find(a->comes_after()))
- job->used_existing_packages_when_ordering()->push_back(a->comes_after());
- }
-
- _order_this(id, false);
- result = true;
+ EdgesFromReasonVisitor edges_from_reason_visitor(_imp->resolved->nag(), ignore_dependencies_from_resolvents, (*r)->resolvent());
+ for (Constraints::ConstIterator c((*r)->constraints()->begin()),
+ c_end((*r)->constraints()->end()) ;
+ c != c_end ; ++c)
+ (*c)->reason()->accept(edges_from_reason_visitor);
}
- return result;
-}
+ _imp->resolved->nag()->verify_edges();
-void
-Orderer::_order_this(const JobID & i, const bool inside_something_else)
-{
- if (! inside_something_else)
- _imp->lists->taken_job_ids()->push_back(i);
- _mark_already_ordered(i);
-}
+ _imp->env->trigger_notifier_callback(NotifierCallbackResolverStageEvent("Finding NAG SCCs"));
+ const std::tr1::shared_ptr<const SortedStronglyConnectedComponents> ssccs(_imp->resolved->nag()->sorted_strongly_connected_components());
-bool
-Orderer::_remove_usable_cycles()
-{
- /* we only want to remove usable jobs... */
- std::set<JobID> removable;
- for (ToOrder::const_iterator i(_imp->to_order.begin()),
- i_end(_imp->to_order.end()) ;
- i != i_end ; ++i)
+ _imp->env->trigger_notifier_callback(NotifierCallbackResolverStageEvent("Ordering SCCs"));
+ for (SortedStronglyConnectedComponents::ConstIterator scc(ssccs->begin()), scc_end(ssccs->end()) ;
+ scc != scc_end ; ++scc)
{
- const std::tr1::shared_ptr<const Job> job(_imp->lists->jobs()->fetch(*i));
- if (simple_visitor_cast<const UsableJob>(*job))
- removable.insert(job->id());
- }
-
- /* but we don't want to remove any job unless it only requires other jobs that
- * we're going to remove. */
- while (true)
- {
- bool need_another_pass(false);
- /* hashes have annoying invalidation rules */
- std::list<JobID> removable_copy(removable.begin(), removable.end());
- for (std::list<JobID>::iterator i(removable_copy.begin()), i_end(removable_copy.end()) ;
- i != i_end ; ++i)
- {
- bool ok(true);
- const std::tr1::shared_ptr<const Job> job(_imp->lists->jobs()->fetch(*i));
- for (ArrowSequence::ConstIterator a(job->arrows()->begin()), a_end(job->arrows()->end()) ;
- a != a_end ; ++a)
- if (_imp->to_order.end() != _imp->to_order.find(a->comes_after()))
- if (removable.end() == removable.find(a->comes_after()))
- {
- need_another_pass = true;
- ok = false;
- break;
- }
-
- if (! ok)
- removable.erase(*i);
- }
-
- if (! need_another_pass)
- break;
- }
-
- if (! removable.empty())
- {
- const std::tr1::shared_ptr<JobIDSequence> ids(new JobIDSequence);
- std::copy(removable.begin(), removable.end(), ids->back_inserter());
+ /* some (or none, or all) of the nodes in our SCC are change or remove
+ * nodes. this matters for cycle resolution. we identify them now, even
+ * though our scc might just contain a single install, rather than
+ * adding in extra useless code for the special easy case. */
+ typedef std::tr1::unordered_set<Resolvent, Hash<Resolvent> > ChangesInSCC;
+ ChangesInSCC changes_in_scc;
+
+ for (Set<Resolvent>::ConstIterator r(scc->nodes()->begin()), r_end(scc->nodes()->end()) ;
+ r != r_end ; ++r)
+ if (_imp->change_or_remove_resolvents.end() != _imp->change_or_remove_resolvents.find(*r))
+ changes_in_scc.insert(*r);
+
+ if (changes_in_scc.empty())
+ {
+ /* two or more installed packages are codependent, but we don't have
+ * to care */
+ }
+ else if (changes_in_scc.size() == 1)
+ {
+ /* there's only one real package in the component, so there's no
+ * need to try anything clever */
+ _schedule(*changes_in_scc.begin(),
+ _imp->change_or_remove_resolvents.find(*changes_in_scc.begin())->second,
+ make_shared_copy(make_named_values<OrdererNotes>(
+ n::cycle_breaking() = ""
+ )));
+ }
+ else
+ {
+ /* whoop de doo. what do our SCCs look like if we only count change
+ * or remove nodes? */
+ NAG scc_nag;
+ for (ChangesInSCC::const_iterator r(changes_in_scc.begin()), r_end(changes_in_scc.end()) ;
+ r != r_end ; ++r)
+ {
+ scc_nag.add_node(*r);
+ /* we only need edges inside our SCC, and only those to other
+ * change or remove nodes */
+ for (NAG::EdgesFromConstIterator e(_imp->resolved->nag()->begin_edges_from(*r)), e_end(_imp->resolved->nag()->end_edges_from(*r)) ;
+ e != e_end ; ++e)
+ if (changes_in_scc.end() != changes_in_scc.find(e->first))
+ scc_nag.add_edge(*r, e->first, e->second);
+ }
- const std::tr1::shared_ptr<UsableGroupJob> usable_group_job(new UsableGroupJob(ids));
- _imp->lists->jobs()->add(usable_group_job);
- _order_this(usable_group_job->id(), false);
+ scc_nag.verify_edges();
- for (std::set<JobID>::iterator i(removable.begin()), i_next(i),
- i_end(removable.end()) ;
- i != i_end ; i = i_next)
- {
- ++i_next;
- _order_this(*i, true);
+ /* now we try again, hopefully with lots of small SCCs now */
+ const std::tr1::shared_ptr<const SortedStronglyConnectedComponents> sub_ssccs(scc_nag.sorted_strongly_connected_components());
+ _order_sub_ssccs(scc_nag, *scc, sub_ssccs, true);
}
}
-
- return ! removable.empty();
}
-void
-Orderer::_cycle_error()
+namespace
{
- std::stringstream s;
- for (ToOrder::const_iterator i(_imp->to_order.begin()),
- i_end(_imp->to_order.end()) ;
- i != i_end ; ++i)
+ std::string nice_resolvent(const Resolvent & r)
{
- s << " {{{" << i->string_id() << " missing";
- const std::tr1::shared_ptr<const Job> job(_imp->lists->jobs()->fetch(*i));
- for (ArrowSequence::ConstIterator a(job->arrows()->begin()), a_end(job->arrows()->end()) ;
- a != a_end ; ++a)
- if (_imp->to_order.end() != _imp->to_order.find(a->comes_after()))
- s << " [" << a->comes_after().string_id() << "]";
- s << " }}}";
+ return stringify(r.package()) + stringify(r.slot());
}
-
- throw InternalError(PALUDIS_HERE, "can't order any of " + s.str());
}
-namespace
+void
+Orderer::_order_sub_ssccs(
+ const NAG & scc_nag,
+ const StronglyConnectedComponent & top_scc,
+ const std::tr1::shared_ptr<const SortedStronglyConnectedComponents> & sub_ssccs,
+ const bool can_recurse)
{
- typedef std::tr1::function<bool (const PackageOrBlockDepSpec &)> AlreadyMetFn;
-
- struct AlreadyMetDep
+ for (SortedStronglyConnectedComponents::ConstIterator sub_scc(sub_ssccs->begin()), sub_scc_end(sub_ssccs->end()) ;
+ sub_scc != sub_scc_end ; ++sub_scc)
{
- bool visit(const DependentReason &) const
- {
- return false;
- }
-
- bool visit(const PresetReason &) const
- {
- return false;
- }
+ if (sub_scc->nodes()->size() == 1)
+ {
+ /* yay. it's all on its own. */
+ _schedule(*sub_scc->nodes()->begin(),
+ _imp->change_or_remove_resolvents.find(*sub_scc->nodes()->begin())->second,
+ make_shared_copy(make_named_values<OrdererNotes>(
+ n::cycle_breaking() = (can_recurse ?
+ "In dependency cycle with existing packages: " + join(scc_nag.begin_nodes(), scc_nag.end_nodes(), ", ", nice_resolvent) :
+ "In dependency cycle with: " + join(top_scc.nodes()->begin(), top_scc.nodes()->end(), ", ", nice_resolvent))
+ )));
+ }
+ else if (no_build_dependencies(*sub_scc->nodes(), scc_nag))
+ {
+ /* what's that, timmy? we have directly codependent nodes?
+ * well i'm jolly glad that's because they're run
+ * dependency cycles which we can order however we like! */
+ for (Set<Resolvent>::ConstIterator r(sub_scc->nodes()->begin()), r_end(sub_scc->nodes()->end()) ;
+ r != r_end ; ++r)
+ _schedule(*r,
+ _imp->change_or_remove_resolvents.find(*r)->second,
+ make_shared_copy(make_named_values<OrdererNotes>(
+ n::cycle_breaking() = "In run dependency cycle with: " + join(
+ sub_scc->nodes()->begin(), sub_scc->nodes()->end(), ", ", nice_resolvent) + (can_recurse ?
+ " in dependency cycle with " + join(top_scc.nodes()->begin(), top_scc.nodes()->end(), ", ", nice_resolvent) : "")
+ )));
+ }
+ else if (can_recurse)
+ {
+ /* no, at least one of the deps is a build dep. let's try
+ * this whole mess again, except without any edges for
+ * dependencies that're already met */
+ NAG scc_nag_without_met_deps;
+ for (Set<Resolvent>::ConstIterator r(sub_scc->nodes()->begin()), r_end(sub_scc->nodes()->end()) ;
+ r != r_end ; ++r)
+ {
+ scc_nag_without_met_deps.add_node(*r);
+ for (NAG::EdgesFromConstIterator e(scc_nag.begin_edges_from(*r)), e_end(scc_nag.end_edges_from(*r)) ;
+ e != e_end ; ++e)
+ if ((! e->second.build_all_met()) || (! e->second.run_all_met()))
+ scc_nag_without_met_deps.add_edge(*r, e->first, make_named_values<NAGEdgeProperties>(
+ n::build() = e->second.build() && ! e->second.build_all_met(),
+ n::build_all_met() = e->second.build_all_met(),
+ n::run() = e->second.run() && ! e->second.run_all_met(),
+ n::run_all_met() = e->second.run_all_met()
+ ));
+ }
- bool visit(const TargetReason &) const
- {
- return false;
- }
+ scc_nag_without_met_deps.verify_edges();
- bool visit(const SetReason & r) const
- {
- return r.reason_for_set()->accept_returning<bool>(*this);
+ const std::tr1::shared_ptr<const SortedStronglyConnectedComponents> sub_ssccs_without_met_deps(
+ scc_nag_without_met_deps.sorted_strongly_connected_components());
+ _order_sub_ssccs(scc_nag_without_met_deps, top_scc, sub_ssccs_without_met_deps, false);
}
-
- bool visit(const DependencyReason & r) const
+ else
{
- return r.already_met();
+ /* all that effort was wasted. there's incest and there's nothing we
+ * can do to fix it. */
+ throw InternalError(PALUDIS_HERE, "circular dependencies we're not smart enough to solve yet: { "
+ + join(sub_scc->nodes()->begin(), sub_scc->nodes()->end(), ", ", nice_resolvent) + " }");
}
- };
+ }
}
-bool
-Orderer::_can_order(const JobID & i, const bool desperate) const
+namespace
{
- const std::tr1::shared_ptr<const Job> job(_imp->lists->jobs()->fetch(i));
- for (ArrowSequence::ConstIterator a(job->arrows()->begin()), a_end(job->arrows()->end()) ;
- a != a_end ; ++a)
+ typedef std::tr1::unordered_set<Resolvent, Hash<Resolvent> > RecursedRequirements;
+
+ void populate_requirements(
+ const std::tr1::shared_ptr<const NAG> & nag,
+ const InstallJobNumbers & install_job_numbers,
+ const Resolvent & resolvent,
+ const std::tr1::shared_ptr<JobRequirements> & requirements,
+ const bool recursing,
+ RecursedRequirements & recursed)
{
- if (_imp->to_order.end() != _imp->to_order.find(a->comes_after()))
- {
- bool skippable(false);
-
- if ((! skippable) && desperate)
+ if (! recursing)
+ for (NAG::EdgesFromConstIterator e(nag->begin_edges_from(resolvent)),
+ e_end(nag->end_edges_from(resolvent)) ;
+ e != e_end ; ++e)
{
- /* we can also ignore any arrows that are already met (e.g a
- * dep b, b dep a, a is already installed */
- if (a->maybe_reason() && a->maybe_reason()->accept_returning<bool>(AlreadyMetDep()))
- skippable = true;
+ if ((! e->second.build_all_met()) || (! e->second.run_all_met()))
+ {
+ InstallJobNumbers::const_iterator n(install_job_numbers.find(e->first));
+ if (n != install_job_numbers.end())
+ requirements->push_back(make_named_values<JobRequirement>(
+ n::job_number() = n->second,
+ n::required_if() = JobRequirementIfs() + jri_require_for_satisfied
+ ));
+ }
}
- if (! skippable)
- return false;
- }
+ if (recursed.insert(resolvent).second)
+ for (NAG::EdgesFromConstIterator e(nag->begin_edges_from(resolvent)),
+ e_end(nag->end_edges_from(resolvent)) ;
+ e != e_end ; ++e)
+ {
+ InstallJobNumbers::const_iterator n(install_job_numbers.find(e->first));
+ if (n != install_job_numbers.end())
+ requirements->push_back(make_named_values<JobRequirement>(
+ n::job_number() = n->second,
+ n::required_if() = JobRequirementIfs() + jri_require_for_independent
+ ));
+ populate_requirements(nag, install_job_numbers, e->first, requirements, true, recursed);
+ }
}
-
- return true;
}
void
-Orderer::_mark_already_ordered(const JobID & i)
+Orderer::_schedule(
+ const Resolvent & resolvent,
+ const std::tr1::shared_ptr<const ChangeOrRemoveDecision> & d,
+ const std::tr1::shared_ptr<const OrdererNotes> & n)
{
- _imp->to_order.erase(i);
- _imp->env->trigger_notifier_callback(NotifierCallbackResolverStepEvent());
+ _imp->resolved->taken_change_or_remove_decisions()->push_back(d, n);
+ if (d->required_confirmations_if_any())
+ _imp->resolved->taken_unconfirmed_change_or_remove_decisions()->push_back(d);
+
+ const ChangesToMakeDecision * const changes_to_make_decision(simple_visitor_cast<const ChangesToMakeDecision>(*d));
+ const RemoveDecision * const remove_decision(simple_visitor_cast<const RemoveDecision>(*d));
+
+ if (changes_to_make_decision)
+ {
+ _imp->resolved->job_lists()->pretend_job_list()->append(make_shared_ptr(new PretendJob(
+ changes_to_make_decision->origin_id())));
+
+ JobNumber fetch_job_n(_imp->resolved->job_lists()->execute_job_list()->append(make_shared_ptr(new FetchJob(
+ make_shared_ptr(new JobRequirements),
+ changes_to_make_decision->origin_id()))));
+
+ const std::tr1::shared_ptr<JobRequirements> requirements(new JobRequirements);
+ requirements->push_back(make_named_values<JobRequirement>(
+ n::job_number() = fetch_job_n,
+ n::required_if() = JobRequirementIfs() + jri_require_for_satisfied + jri_require_for_independent + jri_require_always
+ ));
+
+ RecursedRequirements recursed;
+ populate_requirements(
+ _imp->resolved->nag(),
+ _imp->install_job_numbers,
+ resolvent,
+ requirements,
+ false,
+ recursed
+ );
+
+ JobNumber install_job_n(_imp->resolved->job_lists()->execute_job_list()->append(make_shared_ptr(new InstallJob(
+ requirements,
+ changes_to_make_decision->origin_id(),
+ changes_to_make_decision->destination()->repository(),
+ changes_to_make_decision->resolvent().destination_type(),
+ changes_to_make_decision->destination()->replacing()
+ ))));
+
+ _imp->install_job_numbers.insert(std::make_pair(resolvent, install_job_n));
+ }
+ else if (remove_decision)
+ {
+ _imp->resolved->job_lists()->execute_job_list()->append(make_shared_ptr(new UninstallJob(
+ make_shared_ptr(new JobRequirements),
+ remove_decision->ids()
+ )));
+ }
+ else
+ throw InternalError(PALUDIS_HERE, "huh?");
}
diff --git a/paludis/resolver/orderer.hh b/paludis/resolver/orderer.hh
index 76a8a60..8edc785 100644
--- a/paludis/resolver/orderer.hh
+++ b/paludis/resolver/orderer.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009, 2010 Ciaran McCreesh
+ * 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
@@ -21,22 +21,14 @@
#define PALUDIS_GUARD_PALUDIS_RESOLVER_ORDERER_HH 1
#include <paludis/resolver/orderer-fwd.hh>
-#include <paludis/resolver/resolvent-fwd.hh>
-#include <paludis/resolver/resolution-fwd.hh>
-#include <paludis/resolver/resolutions-fwd.hh>
-#include <paludis/resolver/constraint-fwd.hh>
-#include <paludis/resolver/reason-fwd.hh>
-#include <paludis/resolver/resolver_functions-fwd.hh>
-#include <paludis/resolver/sanitised_dependencies-fwd.hh>
-#include <paludis/resolver/decider-fwd.hh>
-#include <paludis/resolver/resolver-fwd.hh>
-#include <paludis/resolver/job_id-fwd.hh>
-#include <paludis/resolver/job-fwd.hh>
+#include <paludis/resolver/orderer_notes-fwd.hh>
+#include <paludis/resolver/resolved-fwd.hh>
#include <paludis/resolver/decision-fwd.hh>
-#include <paludis/util/attributes.hh>
+#include <paludis/resolver/strongly_connected_component-fwd.hh>
+#include <paludis/resolver/nag-fwd.hh>
+#include <paludis/resolver/resolvent-fwd.hh>
#include <paludis/util/private_implementation_pattern.hh>
-#include <paludis/environment.hh>
-#include <tr1/memory>
+#include <paludis/environment-fwd.hh>
namespace paludis
{
@@ -46,29 +38,21 @@ namespace paludis
private PrivateImplementationPattern<Orderer>
{
private:
- void _resolve_jobs();
- void _resolve_jobs_dep_arrows();
- void _resolve_order();
-
- bool _can_order(const JobID &, const bool desperate) const PALUDIS_ATTRIBUTE((warn_unused_result));
- void _mark_already_ordered(const JobID &);
- void _order_this(const JobID &, const bool inside_something_else);
-
- bool _order_some(const bool desperate, const bool installs_only) PALUDIS_ATTRIBUTE((warn_unused_result));
- bool _remove_usable_cycles() PALUDIS_ATTRIBUTE((warn_unused_result));
- void _cycle_error() PALUDIS_ATTRIBUTE((noreturn));
+ void _schedule(
+ const Resolvent &,
+ const std::tr1::shared_ptr<const ChangeOrRemoveDecision> &,
+ const std::tr1::shared_ptr<const OrdererNotes> &);
- void _confirm(
- const std::tr1::shared_ptr<const Resolution> &,
- const ChangesToMakeDecision &,
- const std::tr1::shared_ptr<SimpleInstallJob> &);
+ void _order_sub_ssccs(
+ const NAG &,
+ const StronglyConnectedComponent & top_scc,
+ const std::tr1::shared_ptr<const SortedStronglyConnectedComponents> & sub_ssccs,
+ const bool can_recurse);
public:
Orderer(
const Environment * const,
- const ResolverFunctions &,
- const std::tr1::shared_ptr<const Decider> &,
- const std::tr1::shared_ptr<ResolverLists> &);
+ const std::tr1::shared_ptr<Resolved> &);
~Orderer();
void resolve();
diff --git a/paludis/resolver/resolver_lists-fwd.hh b/paludis/resolver/orderer_notes-fwd.hh
index 6ae3457..5c105ae 100644
--- a/paludis/resolver/resolver_lists-fwd.hh
+++ b/paludis/resolver/orderer_notes-fwd.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009 Ciaran McCreesh
+ * 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
@@ -17,14 +17,14 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef PALUDIS_GUARD_PALUDIS_RESOLVER_RESOLVER_LISTS_FWD_HH
-#define PALUDIS_GUARD_PALUDIS_RESOLVER_RESOLVER_LISTS_FWD_HH 1
+#ifndef PALUDIS_GUARD_PALUDIS_RESOLVER_ORDERER_NOTES_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_RESOLVER_ORDERER_NOTES_FWD_HH 1
namespace paludis
{
namespace resolver
{
- struct ResolverLists;
+ struct OrdererNotes;
}
}
diff --git a/paludis/resolver/failure_kinds.cc b/paludis/resolver/orderer_notes.cc
index 522960d..f7abd4f 100644
--- a/paludis/resolver/failure_kinds.cc
+++ b/paludis/resolver/orderer_notes.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009 Ciaran McCreesh
+ * 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
@@ -17,14 +17,29 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <paludis/resolver/failure_kinds.hh>
-#include <paludis/util/stringify.hh>
-#include <paludis/util/exception.hh>
-#include <istream>
-#include <ostream>
+#include <paludis/resolver/orderer_notes.hh>
+#include <paludis/util/make_shared_ptr.hh>
+#include <paludis/util/make_named_values.hh>
+#include <paludis/serialise-impl.hh>
using namespace paludis;
using namespace paludis::resolver;
-#include <paludis/resolver/failure_kinds-se.cc>
+void
+OrdererNotes::serialise(Serialiser & s) const
+{
+ s.object("OrdererNotes")
+ .member(SerialiserFlags<>(), "cycle_breaking", cycle_breaking())
+ ;
+}
+
+const std::tr1::shared_ptr<OrdererNotes>
+OrdererNotes::deserialise(Deserialisation & d)
+{
+ Deserialisator v(d, "OrdererNotes");
+
+ return make_shared_ptr(new OrdererNotes(make_named_values<OrdererNotes>(
+ n::cycle_breaking() = v.member<std::string>("cycle_breaking")
+ )));
+}
diff --git a/paludis/resolver/job_id.hh b/paludis/resolver/orderer_notes.hh
index 919d479..49685b2 100644
--- a/paludis/resolver/job_id.hh
+++ b/paludis/resolver/orderer_notes.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009, 2010 Ciaran McCreesh
+ * 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
@@ -17,32 +17,31 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef PALUDIS_GUARD_PALUDIS_RESOLVER_JOB_ID_HH
-#define PALUDIS_GUARD_PALUDIS_RESOLVER_JOB_ID_HH 1
+#ifndef PALUDIS_GUARD_PALUDIS_RESOLVER_ORDERER_NOTES_HH
+#define PALUDIS_GUARD_PALUDIS_RESOLVER_ORDERER_NOTES_HH 1
-#include <paludis/resolver/job_id-fwd.hh>
+#include <paludis/resolver/orderer_notes-fwd.hh>
+#include <paludis/util/attributes.hh>
#include <paludis/util/named_value.hh>
#include <paludis/serialise-fwd.hh>
-#include <string>
+#include <tr1/memory>
namespace paludis
{
namespace n
{
- typedef Name<struct string_id_name> string_id;
+ typedef Name<struct cycle_breaking_name> cycle_breaking;
}
namespace resolver
{
- struct JobID
+ struct OrdererNotes
{
- NamedValue<n::string_id, std::string> string_id;
-
- std::size_t hash() const PALUDIS_ATTRIBUTE((warn_unused_result));
- bool operator< (const JobID &) const PALUDIS_ATTRIBUTE((warn_unused_result));
+ NamedValue<n::cycle_breaking, std::string> cycle_breaking;
void serialise(Serialiser &) const;
- static const JobID deserialise(Deserialisation & d) PALUDIS_ATTRIBUTE((warn_unused_result));
+ static const std::tr1::shared_ptr<OrdererNotes> deserialise(
+ Deserialisation & d) PALUDIS_ATTRIBUTE((warn_unused_result));
};
}
}
diff --git a/paludis/resolver/resolution.cc b/paludis/resolver/resolution.cc
index 6287c6b..ec398a3 100644
--- a/paludis/resolver/resolution.cc
+++ b/paludis/resolver/resolution.cc
@@ -19,7 +19,6 @@
#include <paludis/resolver/resolution.hh>
#include <paludis/resolver/constraint.hh>
-#include <paludis/resolver/arrow.hh>
#include <paludis/resolver/decision.hh>
#include <paludis/util/sequence.hh>
#include <paludis/util/join.hh>
diff --git a/paludis/resolver/resolutions.cc b/paludis/resolver/resolutions.cc
deleted file mode 100644
index dfa99a1..0000000
--- a/paludis/resolver/resolutions.cc
+++ /dev/null
@@ -1,101 +0,0 @@
-/* vim: set sw=4 sts=4 et foldmethod=syntax : */
-
-/*
- * Copyright (c) 2009 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 <paludis/resolver/resolutions.hh>
-#include <paludis/resolver/resolution.hh>
-#include <paludis/util/wrapped_forward_iterator-impl.hh>
-#include <paludis/util/private_implementation_pattern-impl.hh>
-#include <paludis/util/sequence-impl.hh>
-#include <paludis/util/stringify.hh>
-#include <paludis/util/make_named_values.hh>
-#include <paludis/serialise-impl.hh>
-
-using namespace paludis;
-using namespace paludis::resolver;
-
-namespace paludis
-{
- template <>
- struct Implementation<Resolutions>
- {
- Sequence<std::tr1::shared_ptr<Resolution> > resolutions;
- };
-
- template <>
- struct WrappedForwardIteratorTraits<Resolutions::ConstIteratorTag>
- {
- typedef Sequence<std::tr1::shared_ptr<Resolution> >::ConstIterator UnderlyingIterator;
- };
-}
-
-Resolutions::Resolutions() :
- PrivateImplementationPattern<Resolutions>(new Implementation<Resolutions>)
-{
-}
-
-Resolutions::~Resolutions()
-{
-}
-
-void
-Resolutions::append(const std::tr1::shared_ptr<Resolution> & r)
-{
- _imp->resolutions.push_back(r);
-}
-
-Resolutions::ConstIterator
-Resolutions::begin() const
-{
- return ConstIterator(_imp->resolutions.begin());
-}
-
-Resolutions::ConstIterator
-Resolutions::end() const
-{
- return ConstIterator(_imp->resolutions.end());
-}
-
-bool
-Resolutions::empty() const
-{
- return begin() == end();
-}
-
-void
-Resolutions::serialise(Serialiser & s) const
-{
- s.object("Resolutions")
- .member(SerialiserFlags<serialise::container>(), "items", _imp->resolutions)
- ;
-}
-
-const std::tr1::shared_ptr<Resolutions>
-Resolutions::deserialise(Deserialisation & d)
-{
- Deserialisator v(d, "Resolutions");
- Deserialisator vv(*v.find_remove_member("items"), "c");
- std::tr1::shared_ptr<Resolutions> result(new Resolutions);
- for (int n(1), n_end(vv.member<int>("count") + 1) ; n != n_end ; ++n)
- result->append(vv.member<std::tr1::shared_ptr<Resolution> >(stringify(n)));
- return result;
-}
-
-template class PrivateImplementationPattern<Resolutions>;
-template class WrappedForwardIterator<Resolutions::ConstIteratorTag, const std::tr1::shared_ptr<Resolution> >;
-
diff --git a/paludis/resolver/resolutions_by_resolvent-fwd.hh b/paludis/resolver/resolutions_by_resolvent-fwd.hh
new file mode 100644
index 0000000..d75f9fd
--- /dev/null
+++ b/paludis/resolver/resolutions_by_resolvent-fwd.hh
@@ -0,0 +1,31 @@
+/* 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_PALUDIS_RESOLVER_RESOLUTIONS_BY_RESOLVENT_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_RESOLVER_RESOLUTIONS_BY_RESOLVENT_FWD_HH 1
+
+namespace paludis
+{
+ namespace resolver
+ {
+ struct ResolutionsByResolvent;
+ }
+}
+
+#endif
diff --git a/paludis/resolver/resolutions_by_resolvent.cc b/paludis/resolver/resolutions_by_resolvent.cc
new file mode 100644
index 0000000..af8d118
--- /dev/null
+++ b/paludis/resolver/resolutions_by_resolvent.cc
@@ -0,0 +1,119 @@
+/* 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 <paludis/resolver/resolutions_by_resolvent.hh>
+#include <paludis/resolver/resolvent.hh>
+#include <paludis/resolver/resolution.hh>
+#include <paludis/util/private_implementation_pattern-impl.hh>
+#include <paludis/util/wrapped_forward_iterator-impl.hh>
+#include <paludis/util/hashes.hh>
+#include <paludis/util/exception.hh>
+#include <paludis/util/stringify.hh>
+#include <paludis/serialise-impl.hh>
+#include <list>
+#include <tr1/unordered_map>
+
+using namespace paludis;
+using namespace paludis::resolver;
+
+// we need iterators to remain valid after an insert, but we also need fast
+// lookups.
+typedef std::list<std::tr1::shared_ptr<Resolution> > ResolutionList;
+typedef std::tr1::unordered_map<Resolvent, ResolutionList::const_iterator, Hash<Resolvent> > ResolutionListIndex;
+
+namespace paludis
+{
+ template <>
+ struct Implementation<ResolutionsByResolvent>
+ {
+ ResolutionList resolution_list;
+ ResolutionListIndex resolution_list_index;
+ };
+
+ template <>
+ struct WrappedForwardIteratorTraits<ResolutionsByResolvent::ConstIteratorTag>
+ {
+ typedef std::list<std::tr1::shared_ptr<Resolution> >::const_iterator UnderlyingIterator;
+ };
+}
+
+ResolutionsByResolvent::ResolutionsByResolvent() :
+ PrivateImplementationPattern<ResolutionsByResolvent>(new Implementation<ResolutionsByResolvent>)
+{
+}
+
+ResolutionsByResolvent::~ResolutionsByResolvent()
+{
+}
+
+ResolutionsByResolvent::ConstIterator
+ResolutionsByResolvent::begin() const
+{
+ return ConstIterator(_imp->resolution_list.begin());
+}
+
+ResolutionsByResolvent::ConstIterator
+ResolutionsByResolvent::end() const
+{
+ return ConstIterator(_imp->resolution_list.end());
+}
+
+ResolutionsByResolvent::ConstIterator
+ResolutionsByResolvent::find(const Resolvent & r) const
+{
+ ResolutionListIndex::const_iterator x(_imp->resolution_list_index.find(r));
+ if (x == _imp->resolution_list_index.end())
+ return end();
+ else
+ return ConstIterator(x->second);
+}
+
+ResolutionsByResolvent::ConstIterator
+ResolutionsByResolvent::insert_new(const std::tr1::shared_ptr<Resolution> & r)
+{
+ ResolutionList::iterator i(_imp->resolution_list.insert(_imp->resolution_list.end(), r));
+ if (! _imp->resolution_list_index.insert(std::make_pair(r->resolvent(), i)).second)
+ {
+ _imp->resolution_list.erase(i);
+ throw InternalError(PALUDIS_HERE, "duplicate resolution");
+ }
+ return ConstIterator(i);
+}
+
+void
+ResolutionsByResolvent::serialise(Serialiser & s) const
+{
+ s.object("ResolutionsByResolvent")
+ .member(SerialiserFlags<serialise::container>(), "items", _imp->resolution_list)
+ ;
+}
+
+const std::tr1::shared_ptr<ResolutionsByResolvent>
+ResolutionsByResolvent::deserialise(Deserialisation & d)
+{
+ Deserialisator v(d, "ResolutionsByResolvent");
+ Deserialisator vv(*v.find_remove_member("items"), "c");
+ std::tr1::shared_ptr<ResolutionsByResolvent> result(new ResolutionsByResolvent);
+ for (int n(1), n_end(vv.member<int>("count") + 1) ; n != n_end ; ++n)
+ result->insert_new(vv.member<std::tr1::shared_ptr<Resolution> >(stringify(n)));
+ return result;
+}
+
+template class WrappedForwardIterator<ResolutionsByResolvent::ConstIteratorTag, const std::tr1::shared_ptr<Resolution> >;
+
diff --git a/paludis/resolver/resolutions.hh b/paludis/resolver/resolutions_by_resolvent.hh
index 5e865ef..cdb6dc6 100644
--- a/paludis/resolver/resolutions.hh
+++ b/paludis/resolver/resolutions_by_resolvent.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009, 2010 Ciaran McCreesh
+ * 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
@@ -17,48 +17,45 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef PALUDIS_GUARD_PALUDIS_RESOLVER_RESOLUTIONS_HH
-#define PALUDIS_GUARD_PALUDIS_RESOLVER_RESOLUTIONS_HH 1
+#ifndef PALUDIS_GUARD_PALUDIS_RESOLVER_RESOLUTIONS_BY_RESOLVENT_HH
+#define PALUDIS_GUARD_PALUDIS_RESOLVER_RESOLUTIONS_BY_RESOLVENT_HH 1
-#include <paludis/resolver/resolutions-fwd.hh>
+#include <paludis/resolver/resolutions_by_resolvent-fwd.hh>
#include <paludis/resolver/resolution-fwd.hh>
+#include <paludis/resolver/resolvent-fwd.hh>
#include <paludis/util/private_implementation_pattern.hh>
-#include <paludis/util/attributes.hh>
#include <paludis/util/wrapped_forward_iterator.hh>
-#include <paludis/util/named_value.hh>
+#include <paludis/serialise-fwd.hh>
#include <tr1/memory>
namespace paludis
{
namespace resolver
{
- class PALUDIS_VISIBLE Resolutions :
- private PrivateImplementationPattern<Resolutions>
+ class PALUDIS_VISIBLE ResolutionsByResolvent :
+ private PrivateImplementationPattern<ResolutionsByResolvent>
{
public:
- Resolutions();
- ~Resolutions();
-
- void append(const std::tr1::shared_ptr<Resolution> &);
+ ResolutionsByResolvent();
+ ~ResolutionsByResolvent();
struct ConstIteratorTag;
- typedef WrappedForwardIterator<ConstIteratorTag,
- const std::tr1::shared_ptr<Resolution> > ConstIterator;
+ typedef WrappedForwardIterator<ConstIteratorTag, const std::tr1::shared_ptr<Resolution> > ConstIterator;
ConstIterator begin() const PALUDIS_ATTRIBUTE((warn_unused_result));
ConstIterator end() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ ConstIterator find(const Resolvent &) const PALUDIS_ATTRIBUTE((warn_unused_result));
- bool empty() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ ConstIterator insert_new(const std::tr1::shared_ptr<Resolution> &);
void serialise(Serialiser &) const;
- static const std::tr1::shared_ptr<Resolutions> deserialise(
+ static const std::tr1::shared_ptr<ResolutionsByResolvent> deserialise(
Deserialisation & d) PALUDIS_ATTRIBUTE((warn_unused_result));
};
}
#ifdef PALUDIS_HAVE_EXTERN_TEMPLATE
- extern template class PrivateImplementationPattern<resolver::Resolutions>;
- extern template class WrappedForwardIterator<resolver::Resolutions::ConstIteratorTag,
+ extern template class WrappedForwardIterator<resolver::ResolutionsByResolvent::ConstIteratorTag,
const std::tr1::shared_ptr<resolver::Resolution> >;
#endif
}
diff --git a/paludis/resolver/resolved-fwd.hh b/paludis/resolver/resolved-fwd.hh
new file mode 100644
index 0000000..3543633
--- /dev/null
+++ b/paludis/resolver/resolved-fwd.hh
@@ -0,0 +1,33 @@
+/* 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_PALUDIS_RESOLVER_RESOLVED_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_RESOLVER_RESOLVED_FWD_HH 1
+
+#include <paludis/resolver/resolved.hh>
+
+namespace paludis
+{
+ namespace resolver
+ {
+ struct Resolved;
+ }
+}
+
+#endif
diff --git a/paludis/resolver/resolved.cc b/paludis/resolver/resolved.cc
new file mode 100644
index 0000000..61c28bf
--- /dev/null
+++ b/paludis/resolver/resolved.cc
@@ -0,0 +1,71 @@
+/* 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 <paludis/resolver/resolved.hh>
+#include <paludis/resolver/decisions.hh>
+#include <paludis/resolver/decision.hh>
+#include <paludis/resolver/resolutions_by_resolvent.hh>
+#include <paludis/resolver/job_lists.hh>
+#include <paludis/resolver/nag.hh>
+#include <paludis/util/make_named_values.hh>
+#include <paludis/serialise-impl.hh>
+
+using namespace paludis;
+using namespace paludis::resolver;
+
+void
+Resolved::serialise(Serialiser & s) const
+{
+ s.object("Resolved")
+ .member(SerialiserFlags<serialise::might_be_null>(), "job_lists", job_lists())
+ .member(SerialiserFlags<serialise::might_be_null>(), "nag", nag())
+ .member(SerialiserFlags<serialise::might_be_null>(), "resolutions_by_resolvent", resolutions_by_resolvent())
+ .member(SerialiserFlags<serialise::might_be_null>(), "taken_change_or_remove_decisions", taken_change_or_remove_decisions())
+ .member(SerialiserFlags<serialise::might_be_null>(), "taken_unable_to_make_decisions", taken_unable_to_make_decisions())
+ .member(SerialiserFlags<serialise::might_be_null>(), "taken_unconfirmed_change_or_remove_decisions", taken_unconfirmed_change_or_remove_decisions())
+ .member(SerialiserFlags<serialise::might_be_null>(), "untaken_change_or_remove_decisions", untaken_change_or_remove_decisions())
+ .member(SerialiserFlags<serialise::might_be_null>(), "untaken_unable_to_make_decisions", untaken_unable_to_make_decisions())
+ ;
+}
+
+const Resolved
+Resolved::deserialise(Deserialisation & d)
+{
+ Deserialisator v(d, "Resolved");
+
+ return make_named_values<Resolved>(
+ n::job_lists() =
+ v.member<std::tr1::shared_ptr<JobLists> >("job_lists"),
+ n::nag() =
+ v.member<std::tr1::shared_ptr<NAG> >("nag"),
+ n::resolutions_by_resolvent() =
+ v.member<std::tr1::shared_ptr<ResolutionsByResolvent> >("resolutions_by_resolvent"),
+ n::taken_change_or_remove_decisions() =
+ v.member<std::tr1::shared_ptr<OrderedChangeOrRemoveDecisions> >("taken_change_or_remove_decisions"),
+ n::taken_unable_to_make_decisions() =
+ v.member<std::tr1::shared_ptr<Decisions<UnableToMakeDecision> > >("taken_unable_to_make_decisions"),
+ n::taken_unconfirmed_change_or_remove_decisions() =
+ v.member<std::tr1::shared_ptr<Decisions<ChangeOrRemoveDecision> > >("taken_unconfirmed_change_or_remove_decisions"),
+ n::untaken_change_or_remove_decisions() =
+ v.member<std::tr1::shared_ptr<Decisions<ChangeOrRemoveDecision> > >("untaken_change_or_remove_decisions"),
+ n::untaken_unable_to_make_decisions() =
+ v.member<std::tr1::shared_ptr<Decisions<UnableToMakeDecision> > >("untaken_unable_to_make_decisions")
+ );
+}
+
diff --git a/paludis/resolver/resolved.hh b/paludis/resolver/resolved.hh
new file mode 100644
index 0000000..3f99214
--- /dev/null
+++ b/paludis/resolver/resolved.hh
@@ -0,0 +1,66 @@
+/* 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_PALUDIS_RESOLVER_RESOLVED_HH
+#define PALUDIS_GUARD_PALUDIS_RESOLVER_RESOLVED_HH 1
+
+#include <paludis/resolver/resolved-fwd.hh>
+#include <paludis/resolver/decisions-fwd.hh>
+#include <paludis/resolver/resolutions_by_resolvent-fwd.hh>
+#include <paludis/resolver/decision-fwd.hh>
+#include <paludis/resolver/job_lists-fwd.hh>
+#include <paludis/resolver/nag-fwd.hh>
+#include <paludis/util/named_value.hh>
+#include <paludis/serialise-fwd.hh>
+#include <tr1/memory>
+
+namespace paludis
+{
+ namespace n
+ {
+ typedef Name<struct job_lists_name> job_lists;
+ typedef Name<struct nag_name> nag;
+ typedef Name<struct resolutions_by_resolvent_name> resolutions_by_resolvent;
+ typedef Name<struct taken_change_or_remove_decisions_name> taken_change_or_remove_decisions;
+ typedef Name<struct taken_unable_to_make_decisions_name> taken_unable_to_make_decisions;
+ typedef Name<struct taken_unconfirmed_change_or_remove_decisions_name> taken_unconfirmed_change_or_remove_decisions;
+ typedef Name<struct untaken_change_or_remove_decisions_name> untaken_change_or_remove_decisions;
+ typedef Name<struct untaken_unable_to_make_decisions_name> untaken_unable_to_make_decisions;
+ }
+
+ namespace resolver
+ {
+ struct Resolved
+ {
+ NamedValue<n::job_lists, std::tr1::shared_ptr<JobLists> > job_lists;
+ NamedValue<n::nag, std::tr1::shared_ptr<NAG> > nag;
+ NamedValue<n::resolutions_by_resolvent, std::tr1::shared_ptr<ResolutionsByResolvent> > resolutions_by_resolvent;
+ NamedValue<n::taken_change_or_remove_decisions, std::tr1::shared_ptr<OrderedChangeOrRemoveDecisions> > taken_change_or_remove_decisions;
+ NamedValue<n::taken_unable_to_make_decisions, std::tr1::shared_ptr<Decisions<UnableToMakeDecision> > > taken_unable_to_make_decisions;
+ NamedValue<n::taken_unconfirmed_change_or_remove_decisions, std::tr1::shared_ptr<Decisions<ChangeOrRemoveDecision> > > taken_unconfirmed_change_or_remove_decisions;
+ NamedValue<n::untaken_change_or_remove_decisions, std::tr1::shared_ptr<Decisions<ChangeOrRemoveDecision> > > untaken_change_or_remove_decisions;
+ NamedValue<n::untaken_unable_to_make_decisions, std::tr1::shared_ptr<Decisions<UnableToMakeDecision> > > untaken_unable_to_make_decisions;
+
+ static const Resolved deserialise(Deserialisation &) PALUDIS_ATTRIBUTE((warn_unused_result));
+ void serialise(Serialiser &) const;
+ };
+ }
+}
+
+#endif
diff --git a/paludis/resolver/resolvent.hh b/paludis/resolver/resolvent.hh
index e06e33a..0ab218c 100644
--- a/paludis/resolver/resolvent.hh
+++ b/paludis/resolver/resolvent.hh
@@ -25,6 +25,8 @@
#include <paludis/resolver/destination_types-fwd.hh>
#include <paludis/resolver/slot_name_or_null.hh>
#include <paludis/util/named_value.hh>
+#include <paludis/util/sequence.hh>
+#include <paludis/util/wrapped_forward_iterator.hh>
#include <paludis/serialise-fwd.hh>
#include <paludis/dep_spec-fwd.hh>
#include <paludis/package_id-fwd.hh>
@@ -64,6 +66,11 @@ namespace paludis
std::size_t hash() const PALUDIS_ATTRIBUTE((warn_unused_result));
};
}
+
+#ifdef PALUDIS_HAVE_EXTERN_TEMPLATE
+ extern template class Sequence<resolver::Resolvent>;
+ extern template class WrappedForwardIterator<Sequence<resolver::Resolvent>::ConstIteratorTag, const resolver::Resolvent>;
+#endif
}
#endif
diff --git a/paludis/resolver/resolver.cc b/paludis/resolver/resolver.cc
index 65cbad9..a4d3650 100644
--- a/paludis/resolver/resolver.cc
+++ b/paludis/resolver/resolver.cc
@@ -19,15 +19,16 @@
#include <paludis/resolver/resolver.hh>
#include <paludis/resolver/resolver_functions.hh>
-#include <paludis/resolver/resolver_lists.hh>
#include <paludis/resolver/spec_rewriter.hh>
#include <paludis/resolver/decider.hh>
-#include <paludis/resolver/orderer.hh>
#include <paludis/resolver/sanitised_dependencies.hh>
#include <paludis/resolver/reason.hh>
-#include <paludis/resolver/resolutions.hh>
-#include <paludis/resolver/jobs.hh>
-#include <paludis/resolver/job_id.hh>
+#include <paludis/resolver/resolutions_by_resolvent.hh>
+#include <paludis/resolver/orderer.hh>
+#include <paludis/resolver/decisions.hh>
+#include <paludis/resolver/job_list.hh>
+#include <paludis/resolver/job_lists.hh>
+#include <paludis/resolver/nag.hh>
#include <paludis/util/stringify.hh>
#include <paludis/util/make_shared_ptr.hh>
#include <paludis/util/sequence.hh>
@@ -54,7 +55,7 @@ namespace paludis
const Environment * const env;
const ResolverFunctions fns;
- const std::tr1::shared_ptr<ResolverLists> lists;
+ const std::tr1::shared_ptr<Resolved> resolved;
const std::tr1::shared_ptr<Decider> decider;
const std::tr1::shared_ptr<Orderer> orderer;
@@ -62,17 +63,21 @@ namespace paludis
Implementation(const Environment * const e, const ResolverFunctions & f) :
env(e),
fns(f),
- lists(new ResolverLists(make_named_values<ResolverLists>(
- n::all_resolutions() = make_shared_ptr(new Resolutions),
- n::job_ids_needing_confirmation() = make_shared_ptr(new JobIDSequence),
- n::jobs() = make_shared_ptr(new Jobs),
- n::taken_error_job_ids() = make_shared_ptr(new JobIDSequence),
- n::taken_job_ids() = make_shared_ptr(new JobIDSequence),
- n::untaken_error_job_ids() = make_shared_ptr(new JobIDSequence),
- n::untaken_job_ids() = make_shared_ptr(new JobIDSequence)
+ resolved(new Resolved(make_named_values<Resolved>(
+ n::job_lists() = make_shared_copy(make_named_values<JobLists>(
+ n::execute_job_list() = make_shared_ptr(new JobList<ExecuteJob>),
+ n::pretend_job_list() = make_shared_ptr(new JobList<PretendJob>)
+ )),
+ n::nag() = make_shared_ptr(new NAG),
+ n::resolutions_by_resolvent() = make_shared_ptr(new ResolutionsByResolvent),
+ n::taken_change_or_remove_decisions() = make_shared_ptr(new OrderedChangeOrRemoveDecisions),
+ n::taken_unable_to_make_decisions() = make_shared_ptr(new Decisions<UnableToMakeDecision>),
+ n::taken_unconfirmed_change_or_remove_decisions() = make_shared_ptr(new Decisions<ChangeOrRemoveDecision>),
+ n::untaken_change_or_remove_decisions() = make_shared_ptr(new Decisions<ChangeOrRemoveDecision>),
+ n::untaken_unable_to_make_decisions() = make_shared_ptr(new Decisions<UnableToMakeDecision>)
))),
- decider(new Decider(e, f, lists)),
- orderer(new Orderer(e, f, decider, lists))
+ decider(new Decider(e, f, resolved->resolutions_by_resolvent())),
+ orderer(new Orderer(e, resolved))
{
}
};
@@ -163,9 +168,9 @@ Resolver::resolve()
_imp->orderer->resolve();
}
-const std::tr1::shared_ptr<const ResolverLists>
-Resolver::lists() const
+const std::tr1::shared_ptr<const Resolved>
+Resolver::resolved() const
{
- return _imp->lists;
+ return _imp->resolved;
}
diff --git a/paludis/resolver/resolver.hh b/paludis/resolver/resolver.hh
index 53368ef..7473f68 100644
--- a/paludis/resolver/resolver.hh
+++ b/paludis/resolver/resolver.hh
@@ -24,9 +24,7 @@
#include <paludis/resolver/reason-fwd.hh>
#include <paludis/resolver/resolver_functions-fwd.hh>
#include <paludis/resolver/decider-fwd.hh>
-#include <paludis/resolver/orderer-fwd.hh>
-#include <paludis/resolver/resolutions-fwd.hh>
-#include <paludis/resolver/resolver_lists-fwd.hh>
+#include <paludis/resolver/resolved-fwd.hh>
#include <paludis/resolver/sanitised_dependencies-fwd.hh>
#include <paludis/resolver/package_or_block_dep_spec-fwd.hh>
#include <paludis/util/private_implementation_pattern.hh>
@@ -58,7 +56,7 @@ namespace paludis
void resolve();
- const std::tr1::shared_ptr<const ResolverLists> lists() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ const std::tr1::shared_ptr<const Resolved> resolved() const PALUDIS_ATTRIBUTE((warn_unused_result));
};
}
}
diff --git a/paludis/resolver/resolver_TEST_any.cc b/paludis/resolver/resolver_TEST_any.cc
index e0c5f31..fa37066 100644
--- a/paludis/resolver/resolver_TEST_any.cc
+++ b/paludis/resolver/resolver_TEST_any.cc
@@ -22,11 +22,9 @@
#include <paludis/resolver/resolver_functions.hh>
#include <paludis/resolver/resolution.hh>
#include <paludis/resolver/decision.hh>
-#include <paludis/resolver/resolutions.hh>
#include <paludis/resolver/constraint.hh>
#include <paludis/resolver/resolvent.hh>
#include <paludis/resolver/suggest_restart.hh>
-#include <paludis/resolver/resolver_lists.hh>
#include <paludis/environments/test/test_environment.hh>
#include <paludis/util/make_named_values.hh>
#include <paludis/util/options.hh>
@@ -37,6 +35,7 @@
#include <paludis/util/indirect_iterator-impl.hh>
#include <paludis/util/accept_visitor.hh>
#include <paludis/util/tribool.hh>
+#include <paludis/util/make_shared_copy.hh>
#include <paludis/user_dep_spec.hh>
#include <paludis/repository_factory.hh>
#include <paludis/package_database.hh>
@@ -74,30 +73,19 @@ namespace test_cases
void run()
{
- std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("test/target"));
-
- {
- TestMessageSuffix s("taken errors");
- check_resolution_list(resolutions->jobs(), resolutions->taken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("untaken errors");
- check_resolution_list(resolutions->jobs(), resolutions->untaken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
-
- {
- TestMessageSuffix s("ordered");
- check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
- .qpn(QualifiedPackageName("test/target"))
- .finished()
- );
- }
+ std::tr1::shared_ptr<const Resolved> resolved(get_resolved("test/target"));
+
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .change(QualifiedPackageName("test/target"))
+ .finished()),
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished())
+ );
}
} test_empty_alternative;
@@ -111,30 +99,20 @@ namespace test_cases
void run()
{
- std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("test/target"));
-
- {
- TestMessageSuffix s("taken errors");
- check_resolution_list(resolutions->jobs(), resolutions->taken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("untaken errors");
- check_resolution_list(resolutions->jobs(), resolutions->untaken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("ordered");
- check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
- .qpn(QualifiedPackageName("test/dep"))
- .qpn(QualifiedPackageName("test/target"))
- .finished()
- );
- }
+ std::tr1::shared_ptr<const Resolved> resolved(get_resolved("test/target"));
+
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .change(QualifiedPackageName("test/dep"))
+ .change(QualifiedPackageName("test/target"))
+ .finished()),
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished())
+ );
}
} test_empty_alternative_with_upgrade;
@@ -148,29 +126,19 @@ namespace test_cases
void run()
{
- std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("test/target"));
-
- {
- TestMessageSuffix s("taken errors");
- check_resolution_list(resolutions->jobs(), resolutions->taken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("untaken errors");
- check_resolution_list(resolutions->jobs(), resolutions->untaken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("ordered");
- check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
- .qpn(QualifiedPackageName("test/target"))
- .finished()
- );
- }
+ std::tr1::shared_ptr<const Resolved> resolved(get_resolved("test/target"));
+
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .change(QualifiedPackageName("test/target"))
+ .finished()),
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished())
+ );
}
} test_empty_alternative_with_untaken_upgrade;
@@ -191,52 +159,48 @@ namespace test_cases
void run()
{
- std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("preferences/target"));
+ std::tr1::shared_ptr<const Resolved> resolved(get_resolved("preferences/target"));
+
+ std::tr1::shared_ptr<DecisionChecks> checks;
+ if (a.is_true())
{
- TestMessageSuffix s("taken errors");
- check_resolution_list(resolutions->jobs(), resolutions->taken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
+ checks = make_shared_copy(DecisionChecks()
+ .change(QualifiedPackageName("preferences/dep-a"))
+ .change(QualifiedPackageName("preferences/target"))
+ .finished());
}
-
+ else if (b.is_true())
{
- TestMessageSuffix s("untaken errors");
- check_resolution_list(resolutions->jobs(), resolutions->untaken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
+ checks = make_shared_copy(DecisionChecks()
+ .change(QualifiedPackageName("preferences/dep-b"))
+ .change(QualifiedPackageName("preferences/target"))
+ .finished());
}
-
-
+ else if (a.is_false())
+ {
+ checks = make_shared_copy(DecisionChecks()
+ .change(QualifiedPackageName("preferences/dep-middle"))
+ .change(QualifiedPackageName("preferences/target"))
+ .finished());
+ }
+ else
{
- if (a.is_true())
- {
- TestMessageSuffix s("ordered");
- check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
- .qpn(QualifiedPackageName("preferences/dep-a"))
- .qpn(QualifiedPackageName("preferences/target"))
- .finished()
- );
- }
- else if (b.is_true())
- {
- TestMessageSuffix s("ordered");
- check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
- .qpn(QualifiedPackageName("preferences/dep-b"))
- .qpn(QualifiedPackageName("preferences/target"))
- .finished()
- );
- }
- else if (a.is_false())
- {
- TestMessageSuffix s("ordered");
- check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
- .qpn(QualifiedPackageName("preferences/dep-middle"))
- .qpn(QualifiedPackageName("preferences/target"))
- .finished()
- );
- }
+ checks = make_shared_copy(DecisionChecks()
+ .change(QualifiedPackageName("preferences/dep-a"))
+ .change(QualifiedPackageName("preferences/target"))
+ .finished());
}
+
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = checks,
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished())
+ );
}
} test_empty_preferences_tt(true, true),
test_empty_preferences_ti(true, indeterminate), test_empty_preferences_tf(true, false),
diff --git a/paludis/resolver/resolver_TEST_blockers.cc b/paludis/resolver/resolver_TEST_blockers.cc
index dd6cbda..3ea617f 100644
--- a/paludis/resolver/resolver_TEST_blockers.cc
+++ b/paludis/resolver/resolver_TEST_blockers.cc
@@ -21,11 +21,9 @@
#include <paludis/resolver/resolver_functions.hh>
#include <paludis/resolver/resolution.hh>
#include <paludis/resolver/decision.hh>
-#include <paludis/resolver/resolutions.hh>
#include <paludis/resolver/constraint.hh>
#include <paludis/resolver/resolvent.hh>
#include <paludis/resolver/suggest_restart.hh>
-#include <paludis/resolver/resolver_lists.hh>
#include <paludis/environments/test/test_environment.hh>
#include <paludis/util/make_named_values.hh>
#include <paludis/util/options.hh>
@@ -35,6 +33,7 @@
#include <paludis/util/map.hh>
#include <paludis/util/indirect_iterator-impl.hh>
#include <paludis/util/accept_visitor.hh>
+#include <paludis/util/make_shared_copy.hh>
#include <paludis/user_dep_spec.hh>
#include <paludis/repository_factory.hh>
#include <paludis/package_database.hh>
@@ -57,8 +56,8 @@ namespace
{
struct ResolverBlockersTestCase : ResolverTestCase
{
- ResolverBlockersTestCase(const std::string & s) :
- ResolverTestCase("blockers", s, "exheres-0", "exheres")
+ ResolverBlockersTestCase(const std::string & s, const std::string & e = "exheres-0") :
+ ResolverTestCase("blockers", s, e, "exheres")
{
}
};
@@ -80,31 +79,20 @@ namespace test_cases
void run()
{
- std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("hard/target"));
-
- {
- TestMessageSuffix s("taken errors");
- check_resolution_list(resolutions->jobs(), resolutions->taken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("untaken errors");
- check_resolution_list(resolutions->jobs(), resolutions->untaken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("ordered");
- check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
- .qpn(QualifiedPackageName("hard/a-pkg"))
- .qpn(QualifiedPackageName("hard/z-pkg"))
- .qpn(QualifiedPackageName("hard/target"))
- .finished()
- );
- }
+ std::tr1::shared_ptr<const Resolved> resolved(get_resolved("hard/target"));
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .change(QualifiedPackageName("hard/a-pkg"))
+ .change(QualifiedPackageName("hard/z-pkg"))
+ .change(QualifiedPackageName("hard/target"))
+ .finished()),
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished())
+ );
}
} test_hard_blocker(false), test_hard_blocker_transient(true);
@@ -121,30 +109,19 @@ namespace test_cases
void run()
{
- std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("unfixable/target"));
-
- {
- TestMessageSuffix s("taken errors");
- check_resolution_list(resolutions->jobs(), resolutions->taken_error_job_ids(), ResolutionListChecks()
- .kind("unable_to_make_decision", QualifiedPackageName("unfixable/a-pkg"))
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("untaken errors");
- check_resolution_list(resolutions->jobs(), resolutions->untaken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("ordered");
- check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
- .qpn(QualifiedPackageName("unfixable/target"))
- .finished()
- );
- }
+ std::tr1::shared_ptr<const Resolved> resolved(get_resolved("unfixable/target"));
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .change(QualifiedPackageName("unfixable/target"))
+ .finished()),
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .unable(QualifiedPackageName("unfixable/a-pkg"))
+ .finished()),
+ n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished())
+ );
}
} test_unfixable_blocker(false), test_unfixable_blocker_transient(true);
@@ -162,30 +139,19 @@ namespace test_cases
void run()
{
- std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("remove/target"));
-
- {
- TestMessageSuffix s("taken errors");
- check_resolution_list(resolutions->jobs(), resolutions->taken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("untaken errors");
- check_resolution_list(resolutions->jobs(), resolutions->untaken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("ordered");
- check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
- .kind("remove_decision", QualifiedPackageName("remove/a-pkg"))
- .qpn(QualifiedPackageName("remove/target"))
- .finished()
- );
- }
+ std::tr1::shared_ptr<const Resolved> resolved(get_resolved("remove/target"));
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .remove(QualifiedPackageName("remove/a-pkg"))
+ .change(QualifiedPackageName("remove/target"))
+ .finished()),
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished())
+ );
}
} test_remove_blocker(false), test_remove_blocker_transient(true);
@@ -205,38 +171,23 @@ namespace test_cases
void run()
{
- std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions(BlockDepSpec(
+ std::tr1::shared_ptr<const Resolved> resolved(get_resolved(BlockDepSpec(
"!target/target",
parse_user_package_dep_spec("target/target", &env, UserPackageDepSpecOptions()),
false)));
- {
- TestMessageSuffix s("taken errors");
- check_resolution_list(resolutions->jobs(), resolutions->taken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("untaken errors");
- check_resolution_list(resolutions->jobs(), resolutions->untaken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("ordered");
-
- if (exists)
- check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
- .kind("remove_decision", QualifiedPackageName("target/target"))
- .finished()
- );
- else
- check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = exists ? make_shared_copy(DecisionChecks()
+ .remove(QualifiedPackageName("target/target"))
+ .finished()) : make_shared_copy(DecisionChecks()
+ .finished()),
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished())
+ );
}
} test_target(false), test_target_exists(true);
@@ -261,27 +212,65 @@ namespace test_cases
void run()
{
- std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("blocked-and-dep/target"));
-
- {
- TestMessageSuffix s("taken errors");
- check_resolution_list(resolutions->jobs(), resolutions->taken_error_job_ids(), ResolutionListChecks()
- .kind("unable_to_make_decision", QualifiedPackageName("blocked-and-dep/both"))
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("ordered");
- check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
- .kind("changes_to_make", QualifiedPackageName("blocked-and-dep/target"))
- .finished()
- );
- }
+ std::tr1::shared_ptr<const Resolved> resolved(get_resolved("blocked-and-dep/target"));
+
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .change(QualifiedPackageName("blocked-and-dep/target"))
+ .finished()),
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .unable(QualifiedPackageName("blocked-and-dep/both"))
+ .finished()),
+ n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished())
+ );
}
} test_blocked_and_dep(false, false),
test_blocked_and_dep_exists(true, false),
test_blocked_and_dep_allowed(false, true),
test_blocked_and_dep_exists_allowed(true, true);
+
+ struct BlockAndDepCycle : ResolverBlockersTestCase
+ {
+ BlockAndDepCycle() :
+ ResolverBlockersTestCase("block and dep cycle", "0")
+ {
+ install("block-and-dep-cycle", "target", "0");
+ }
+
+ void run()
+ {
+ std::tr1::shared_ptr<const Resolved> resolved(get_resolved("block-and-dep-cycle/target"));
+
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .change(QualifiedPackageName("block-and-dep-cycle/dep"))
+ .change(QualifiedPackageName("block-and-dep-cycle/target"))
+ .finished()),
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished())
+ );
+ }
+ } test_block_and_dep_cycle;
+
+ struct HardBlockAndDepCycle : ResolverBlockersTestCase
+ {
+ HardBlockAndDepCycle() :
+ ResolverBlockersTestCase("hard block and dep cycle", "0")
+ {
+ install("hard-block-and-dep-cycle", "target", "0");
+ }
+
+ void run()
+ {
+ TEST_CHECK_THROWS(get_resolved("hard-block-and-dep-cycle/target"), Exception);
+ }
+ } test_hard_block_and_dep_cycle;
}
diff --git a/paludis/resolver/resolver_TEST_blockers_setup.sh b/paludis/resolver/resolver_TEST_blockers_setup.sh
index 5b7a810..1381960 100755
--- a/paludis/resolver/resolver_TEST_blockers_setup.sh
+++ b/paludis/resolver/resolver_TEST_blockers_setup.sh
@@ -14,6 +14,11 @@ cd repo
echo "repo" > profiles/repo_name
: > metadata/categories.conf
+: > profiles/categories
+cat <<'END' > profiles/profile/make.defaults
+ARCH=test
+END
+
# hard
echo 'hard' >> metadata/categories.conf
@@ -101,5 +106,55 @@ PLATFORMS="test"
SLOT="0"
END
+# block-and-dep-cycle
+echo 'block-and-dep-cycle' >> metadata/categories.conf
+
+mkdir -p 'packages/block-and-dep-cycle/target'
+cat <<END > packages/block-and-dep-cycle/target/target-1.ebuild
+EAPI="2"
+DESCRIPTION="target"
+KEYWORDS="test"
+SLOT="0"
+DEPEND="
+ block-and-dep-cycle/dep
+ "
+END
+
+mkdir -p 'packages/block-and-dep-cycle/dep'
+cat <<END > packages/block-and-dep-cycle/dep/dep-1.ebuild
+EAPI="2"
+DESCRIPTION="dep"
+KEYWORDS="test"
+SLOT="0"
+DEPEND="
+ !=block-and-dep-cycle/target-0
+ "
+END
+
+# hard-block-and-dep-cycle
+echo 'hard-block-and-dep-cycle' >> metadata/categories.conf
+
+mkdir -p 'packages/hard-block-and-dep-cycle/target'
+cat <<END > packages/hard-block-and-dep-cycle/target/target-1.ebuild
+EAPI="2"
+DESCRIPTION="target"
+KEYWORDS="test"
+SLOT="0"
+DEPEND="
+ hard-block-and-dep-cycle/dep
+ "
+END
+
+mkdir -p 'packages/hard-block-and-dep-cycle/dep'
+cat <<END > packages/hard-block-and-dep-cycle/dep/dep-1.ebuild
+EAPI="2"
+DESCRIPTION="dep"
+KEYWORDS="test"
+SLOT="0"
+DEPEND="
+ !!=hard-block-and-dep-cycle/target-0
+ "
+END
+
cd ..
diff --git a/paludis/resolver/resolver_TEST_continue_on_failure.cc b/paludis/resolver/resolver_TEST_continue_on_failure.cc
new file mode 100644
index 0000000..597d693
--- /dev/null
+++ b/paludis/resolver/resolver_TEST_continue_on_failure.cc
@@ -0,0 +1,159 @@
+/* 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 <paludis/resolver/resolver.hh>
+#include <paludis/resolver/resolver_functions.hh>
+#include <paludis/resolver/resolution.hh>
+#include <paludis/resolver/decision.hh>
+#include <paludis/resolver/constraint.hh>
+#include <paludis/resolver/resolvent.hh>
+#include <paludis/resolver/suggest_restart.hh>
+#include <paludis/resolver/job_lists.hh>
+#include <paludis/resolver/job_list.hh>
+#include <paludis/resolver/job.hh>
+#include <paludis/resolver/job_requirements.hh>
+#include <paludis/environments/test/test_environment.hh>
+#include <paludis/util/make_named_values.hh>
+#include <paludis/util/options.hh>
+#include <paludis/util/wrapped_forward_iterator-impl.hh>
+#include <paludis/util/make_shared_ptr.hh>
+#include <paludis/util/sequence.hh>
+#include <paludis/util/map-impl.hh>
+#include <paludis/util/indirect_iterator-impl.hh>
+#include <paludis/util/accept_visitor.hh>
+#include <paludis/util/tribool.hh>
+#include <paludis/util/make_shared_copy.hh>
+#include <paludis/util/simple_visitor_cast.hh>
+#include <paludis/user_dep_spec.hh>
+#include <paludis/repository_factory.hh>
+#include <paludis/package_database.hh>
+
+#include <paludis/resolver/resolver_test.hh>
+#include <test/test_runner.hh>
+#include <test/test_framework.hh>
+
+#include <list>
+#include <tr1/functional>
+#include <algorithm>
+#include <map>
+
+using namespace paludis;
+using namespace paludis::resolver;
+using namespace paludis::resolver::resolver_test;
+using namespace test;
+
+namespace
+{
+ struct ResolverContinueOnFailureTestCase : ResolverTestCase
+ {
+ ResolverContinueOnFailureTestCase(const std::string & s) :
+ ResolverTestCase("continue_on_failure", s, "exheres-0", "exheres")
+ {
+ }
+ };
+
+ UseExisting
+ use_existing_if_same(
+ const std::tr1::shared_ptr<const Resolution> &,
+ const PackageDepSpec &,
+ const std::tr1::shared_ptr<const Reason> &)
+ {
+ return ue_if_same;
+ }
+
+ std::string
+ stringify_req(const JobRequirement & r)
+ {
+ std::stringstream result;
+ result << r.job_number();
+ if (r.required_if()[jri_require_for_satisfied])
+ result << " satisfied";
+ if (r.required_if()[jri_require_for_independent])
+ result << " independent";
+ if (r.required_if()[jri_require_always])
+ result << " always";
+ return result.str();
+ }
+}
+
+namespace test_cases
+{
+ struct TestContinueOnFailure : ResolverContinueOnFailureTestCase
+ {
+ const bool direct_dep_installed;
+
+ TestContinueOnFailure(const bool d) :
+ ResolverContinueOnFailureTestCase("continue on failure " + stringify(d)),
+ direct_dep_installed(d)
+ {
+ if (d)
+ install("continue-on-failure", "direct-dep", "0");
+ install("continue-on-failure", "unchanged-dep", "1")->build_dependencies_key()->set_from_string("continue-on-failure/indirect-dep");
+ }
+
+ virtual ResolverFunctions get_resolver_functions(InitialConstraints & initial_constraints)
+ {
+ ResolverFunctions result(ResolverContinueOnFailureTestCase::get_resolver_functions(initial_constraints));
+ result.get_use_existing_fn() = std::tr1::bind(&use_existing_if_same, std::tr1::placeholders::_1,
+ std::tr1::placeholders::_2, std::tr1::placeholders::_3);
+ return result;
+ }
+
+ void run()
+ {
+ std::tr1::shared_ptr<const Resolved> resolved(get_resolved("continue-on-failure/target"));
+
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .change(QualifiedPackageName("continue-on-failure/direct-dep"))
+ .change(QualifiedPackageName("continue-on-failure/indirect-dep"))
+ .change(QualifiedPackageName("continue-on-failure/target"))
+ .finished()),
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished())
+ );
+
+ TEST_CHECK_EQUAL(resolved->job_lists()->execute_job_list()->length(), 6);
+
+ const InstallJob * const direct_dep_job(simple_visitor_cast<const InstallJob>(**resolved->job_lists()->execute_job_list()->fetch(1)));
+ TEST_CHECK(direct_dep_job);
+ TEST_CHECK_EQUAL(join(direct_dep_job->requirements()->begin(), direct_dep_job->requirements()->end(), ", ", stringify_req),
+ "0 satisfied independent always");
+
+ const InstallJob * const indirect_dep_job(simple_visitor_cast<const InstallJob>(**resolved->job_lists()->execute_job_list()->fetch(3)));
+ TEST_CHECK(indirect_dep_job);
+ TEST_CHECK_EQUAL(join(indirect_dep_job->requirements()->begin(), indirect_dep_job->requirements()->end(), ", ", stringify_req),
+ "2 satisfied independent always");
+
+ const InstallJob * const target_job(simple_visitor_cast<const InstallJob>(**resolved->job_lists()->execute_job_list()->fetch(5)));
+ TEST_CHECK(target_job);
+ if (direct_dep_installed)
+ TEST_CHECK_EQUAL(join(target_job->requirements()->begin(), target_job->requirements()->end(), ", ", stringify_req),
+ "4 satisfied independent always, 3 independent, 1 independent");
+ else
+ TEST_CHECK_EQUAL(join(target_job->requirements()->begin(), target_job->requirements()->end(), ", ", stringify_req),
+ "4 satisfied independent always, 1 satisfied, 3 independent, 1 independent");
+ }
+ } test_continue_on_failure_false(false), test_continue_on_failure_true(true);
+}
+
diff --git a/paludis/resolver/resolver_TEST_continue_on_failure_cleanup.sh b/paludis/resolver/resolver_TEST_continue_on_failure_cleanup.sh
new file mode 100755
index 0000000..849bc51
--- /dev/null
+++ b/paludis/resolver/resolver_TEST_continue_on_failure_cleanup.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+# vim: set ft=sh sw=4 sts=4 et :
+
+if [ -d resolver_TEST_continue_on_failure_dir ] ; then
+ rm -fr resolver_TEST_continue_on_failure_dir
+else
+ true
+fi
+
diff --git a/paludis/resolver/resolver_TEST_continue_on_failure_setup.sh b/paludis/resolver/resolver_TEST_continue_on_failure_setup.sh
new file mode 100755
index 0000000..ffa8f7c
--- /dev/null
+++ b/paludis/resolver/resolver_TEST_continue_on_failure_setup.sh
@@ -0,0 +1,56 @@
+#!/usr/bin/env bash
+# vim: set ft=sh sw=4 sts=4 et :
+
+mkdir resolver_TEST_continue_on_failure_dir || exit 1
+cd resolver_TEST_continue_on_failure_dir || exit 1
+
+mkdir -p build
+mkdir -p distdir
+mkdir -p installed
+
+mkdir -p repo/{profiles/profile,metadata}
+
+cd repo
+echo "repo" > profiles/repo_name
+: > metadata/categories.conf
+
+# continue-on-failure
+echo 'continue-on-failure' >> metadata/categories.conf
+
+mkdir -p 'packages/continue-on-failure/target'
+cat <<END > packages/continue-on-failure/target/target-1.exheres-0
+SUMMARY="target"
+PLATFORMS="test"
+SLOT="0"
+DEPENDENCIES="
+ continue-on-failure/unchanged-dep
+ continue-on-failure/direct-dep
+ "
+END
+
+mkdir -p 'packages/continue-on-failure/direct-dep'
+cat <<END > packages/continue-on-failure/direct-dep/direct-dep-1.exheres-0
+SUMMARY="dep"
+PLATFORMS="test"
+SLOT="0"
+END
+
+mkdir -p 'packages/continue-on-failure/unchanged-dep'
+cat <<END > packages/continue-on-failure/unchanged-dep/unchanged-dep-1.exheres-0
+SUMMARY="dep"
+PLATFORMS="test"
+SLOT="0"
+DEPENDENCIES="
+ continue-on-failure/indirect-dep
+ "
+END
+
+mkdir -p 'packages/continue-on-failure/indirect-dep'
+cat <<END > packages/continue-on-failure/indirect-dep/indirect-dep-1.exheres-0
+SUMMARY="dep"
+PLATFORMS="test"
+SLOT="0"
+END
+
+cd ..
+
diff --git a/paludis/resolver/resolver_TEST_cycles.cc b/paludis/resolver/resolver_TEST_cycles.cc
index ed1ab0c..1597be5 100644
--- a/paludis/resolver/resolver_TEST_cycles.cc
+++ b/paludis/resolver/resolver_TEST_cycles.cc
@@ -21,11 +21,9 @@
#include <paludis/resolver/resolver_functions.hh>
#include <paludis/resolver/resolution.hh>
#include <paludis/resolver/decision.hh>
-#include <paludis/resolver/resolutions.hh>
#include <paludis/resolver/constraint.hh>
#include <paludis/resolver/resolvent.hh>
#include <paludis/resolver/suggest_restart.hh>
-#include <paludis/resolver/resolver_lists.hh>
#include <paludis/environments/test/test_environment.hh>
#include <paludis/util/make_named_values.hh>
#include <paludis/util/options.hh>
@@ -35,6 +33,7 @@
#include <paludis/util/map.hh>
#include <paludis/util/indirect_iterator-impl.hh>
#include <paludis/util/accept_visitor.hh>
+#include <paludis/util/make_shared_copy.hh>
#include <paludis/user_dep_spec.hh>
#include <paludis/repository_factory.hh>
#include <paludis/package_database.hh>
@@ -65,7 +64,7 @@ namespace
UseExisting
use_existing_if_same(
- const Resolvent &,
+ const std::tr1::shared_ptr<const Resolution> &,
const PackageDepSpec &,
const std::tr1::shared_ptr<const Reason> &)
{
@@ -94,29 +93,19 @@ namespace test_cases
void run()
{
- std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("no-changes/target"));
-
- {
- TestMessageSuffix s("taken errors");
- check_resolution_list(resolutions->jobs(), resolutions->taken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("untaken errors");
- check_resolution_list(resolutions->jobs(), resolutions->untaken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("ordered");
- check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
- .qpn(QualifiedPackageName("no-changes/target"))
- .finished()
- );
- }
+ std::tr1::shared_ptr<const Resolved> resolved(get_resolved("no-changes/target"));
+
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .change(QualifiedPackageName("no-changes/target"))
+ .finished()),
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished())
+ );
}
} test_no_changes;
@@ -130,30 +119,20 @@ namespace test_cases
void run()
{
- std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("existing-usable/target"));
-
- {
- TestMessageSuffix s("taken errors");
- check_resolution_list(resolutions->jobs(), resolutions->taken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("untaken errors");
- check_resolution_list(resolutions->jobs(), resolutions->untaken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("ordered");
- check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
- .qpn(QualifiedPackageName("existing-usable/target"))
- .qpn(QualifiedPackageName("existing-usable/dep"))
- .finished()
- );
- }
+ std::tr1::shared_ptr<const Resolved> resolved(get_resolved("existing-usable/target"));
+
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .change(QualifiedPackageName("existing-usable/target"))
+ .change(QualifiedPackageName("existing-usable/dep"))
+ .finished()),
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished())
+ );
}
} test_existing_usable;
@@ -163,32 +142,22 @@ namespace test_cases
void run()
{
- std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("mutual-run-deps/target"));
-
- {
- TestMessageSuffix s("taken errors");
- check_resolution_list(resolutions->jobs(), resolutions->taken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("untaken errors");
- check_resolution_list(resolutions->jobs(), resolutions->untaken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("ordered");
- check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
- .qpn(QualifiedPackageName("mutual-run-deps/dep-a"))
- .qpn(QualifiedPackageName("mutual-run-deps/dep-b"))
- .qpn(QualifiedPackageName("mutual-run-deps/dep-c"))
- .qpn(QualifiedPackageName("mutual-run-deps/target"))
- .finished()
- );
- }
+ std::tr1::shared_ptr<const Resolved> resolved(get_resolved("mutual-run-deps/target"));
+
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .change(QualifiedPackageName("mutual-run-deps/dep-a"))
+ .change(QualifiedPackageName("mutual-run-deps/dep-b"))
+ .change(QualifiedPackageName("mutual-run-deps/dep-c"))
+ .change(QualifiedPackageName("mutual-run-deps/target"))
+ .finished()),
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished())
+ );
}
} test_mutual_run_deps;
@@ -198,8 +167,68 @@ namespace test_cases
void run()
{
- TEST_CHECK_THROWS(get_resolutions("mutual-build-deps/target"), Exception);
+ TEST_CHECK_THROWS(get_resolved("mutual-build-deps/target"), Exception);
}
} test_mutual_build_deps;
+
+ struct TestTriangle : ResolverCyclesTestCase
+ {
+ const bool b_installed;
+ const bool c_installed;
+
+ TestTriangle(bool b, bool c) :
+ ResolverCyclesTestCase("triangle " + stringify(b) + " " + stringify(c)),
+ b_installed(b),
+ c_installed(c)
+ {
+ if (b_installed)
+ install("triangle", "dep-b", "1");
+ if (c_installed)
+ install("triangle", "dep-c", "1");
+ }
+
+ void run()
+ {
+ if ((! b_installed) && (! c_installed))
+ {
+ TEST_CHECK_THROWS(get_resolved("triangle/target"), Exception);
+ return;
+ }
+
+ std::tr1::shared_ptr<const Resolved> resolved(get_resolved("triangle/target"));
+ std::tr1::shared_ptr<DecisionChecks> checks;
+
+ if (b_installed)
+ {
+ checks = make_shared_copy(DecisionChecks()
+ .change(QualifiedPackageName("triangle/dep-c"))
+ .change(QualifiedPackageName("triangle/dep-a"))
+ .change(QualifiedPackageName("triangle/dep-b"))
+ .change(QualifiedPackageName("triangle/target"))
+ .finished());
+ }
+ else if (c_installed)
+ {
+ checks = make_shared_copy(DecisionChecks()
+ .change(QualifiedPackageName("triangle/dep-a"))
+ .change(QualifiedPackageName("triangle/dep-b"))
+ .change(QualifiedPackageName("triangle/dep-c"))
+ .change(QualifiedPackageName("triangle/target"))
+ .finished());
+ }
+ else
+ TEST_CHECK(false);
+
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = checks,
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished())
+ );
+ }
+ } test_triangle_none(false, false), test_triangle_b(true, false), test_triangle_c(false, true);
}
diff --git a/paludis/resolver/resolver_TEST_cycles_setup.sh b/paludis/resolver/resolver_TEST_cycles_setup.sh
index 762cad0..a3ca2b3 100755
--- a/paludis/resolver/resolver_TEST_cycles_setup.sh
+++ b/paludis/resolver/resolver_TEST_cycles_setup.sh
@@ -130,5 +130,40 @@ SLOT="0"
DEPENDENCIES="build: mutual-build-deps/dep-b"
END
+# triangle
+echo 'triangle' >> metadata/categories.conf
+
+mkdir -p 'packages/triangle/target'
+cat <<END > packages/triangle/target/target-1.exheres-0
+SUMMARY="target"
+PLATFORMS="test"
+SLOT="0"
+DEPENDENCIES="triangle/dep-c"
+END
+
+mkdir -p 'packages/triangle/dep-a'
+cat <<END > packages/triangle/dep-a/dep-a-1.exheres-0
+SUMMARY="target"
+PLATFORMS="test"
+SLOT="0"
+DEPENDENCIES="run: triangle/dep-b build: triangle/dep-c"
+END
+
+mkdir -p 'packages/triangle/dep-b'
+cat <<END > packages/triangle/dep-b/dep-b-1.exheres-0
+SUMMARY="target"
+PLATFORMS="test"
+SLOT="0"
+DEPENDENCIES="run: triangle/dep-a build: triangle/dep-c"
+END
+
+mkdir -p 'packages/triangle/dep-c'
+cat <<END > packages/triangle/dep-c/dep-c-1.exheres-0
+SUMMARY="target"
+PLATFORMS="test"
+SLOT="0"
+DEPENDENCIES="run: triangle/dep-b"
+END
+
cd ..
diff --git a/paludis/resolver/resolver_TEST_errors.cc b/paludis/resolver/resolver_TEST_errors.cc
index 0721be9..7c0ce0b 100644
--- a/paludis/resolver/resolver_TEST_errors.cc
+++ b/paludis/resolver/resolver_TEST_errors.cc
@@ -21,11 +21,9 @@
#include <paludis/resolver/resolver_functions.hh>
#include <paludis/resolver/resolution.hh>
#include <paludis/resolver/decision.hh>
-#include <paludis/resolver/resolutions.hh>
#include <paludis/resolver/constraint.hh>
#include <paludis/resolver/resolvent.hh>
#include <paludis/resolver/suggest_restart.hh>
-#include <paludis/resolver/resolver_lists.hh>
#include <paludis/environments/test/test_environment.hh>
#include <paludis/util/make_named_values.hh>
#include <paludis/util/options.hh>
@@ -35,6 +33,7 @@
#include <paludis/util/map.hh>
#include <paludis/util/indirect_iterator-impl.hh>
#include <paludis/util/accept_visitor.hh>
+#include <paludis/util/make_shared_copy.hh>
#include <paludis/user_dep_spec.hh>
#include <paludis/repository_factory.hh>
#include <paludis/package_database.hh>
@@ -72,32 +71,21 @@ namespace test_cases
void run()
{
- std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("unable-to-decide-then-more/target"));
+ std::tr1::shared_ptr<const Resolved> resolved(get_resolved("unable-to-decide-then-more/target"));
- {
- TestMessageSuffix s("taken errors");
- check_resolution_list(resolutions->jobs(), resolutions->taken_error_job_ids(), ResolutionListChecks()
- .kind("unable_to_make_decision", QualifiedPackageName("unable-to-decide-then-more/pkg-a"))
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("untaken errors");
- check_resolution_list(resolutions->jobs(), resolutions->untaken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
-
- {
- TestMessageSuffix s("ordered");
- check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
- .qpn(QualifiedPackageName("unable-to-decide-then-more/pkg-b"))
- .qpn(QualifiedPackageName("unable-to-decide-then-more/target"))
- .finished()
- );
- }
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .change(QualifiedPackageName("unable-to-decide-then-more/pkg-b"))
+ .change(QualifiedPackageName("unable-to-decide-then-more/target"))
+ .finished()),
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .unable(QualifiedPackageName("unable-to-decide-then-more/pkg-a"))
+ .finished()),
+ n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished())
+ );
}
} test_unable_to_decide_then_more;
}
diff --git a/paludis/resolver/resolver_TEST_serialisation.cc b/paludis/resolver/resolver_TEST_serialisation.cc
index 422db69..2b0c7e8 100644
--- a/paludis/resolver/resolver_TEST_serialisation.cc
+++ b/paludis/resolver/resolver_TEST_serialisation.cc
@@ -21,16 +21,15 @@
#include <paludis/resolver/resolver_functions.hh>
#include <paludis/resolver/resolution.hh>
#include <paludis/resolver/decision.hh>
-#include <paludis/resolver/resolutions.hh>
#include <paludis/resolver/constraint.hh>
#include <paludis/resolver/resolvent.hh>
#include <paludis/resolver/suggest_restart.hh>
-#include <paludis/resolver/resolver_lists.hh>
#include <paludis/environments/test/test_environment.hh>
#include <paludis/util/make_named_values.hh>
#include <paludis/util/options.hh>
#include <paludis/util/wrapped_forward_iterator-impl.hh>
#include <paludis/util/make_shared_ptr.hh>
+#include <paludis/util/make_shared_copy.hh>
#include <paludis/util/sequence.hh>
#include <paludis/util/map.hh>
#include <paludis/util/indirect_iterator-impl.hh>
@@ -74,50 +73,33 @@ namespace test_cases
void run()
{
- std::tr1::shared_ptr<const ResolverLists> resolutions;
+ std::tr1::shared_ptr<const Resolved> resolved;
{
- std::tr1::shared_ptr<const ResolverLists> orig_resolutions(get_resolutions("serialisation/target"));
+ std::tr1::shared_ptr<const Resolved> orig_resolved(get_resolved("serialisation/target"));
StringListStream str;
Serialiser ser(str);
- orig_resolutions->serialise(ser);
+ orig_resolved->serialise(ser);
str.nothing_more_to_write();
Deserialiser deser(&env, str);
Deserialisation desern("ResolverLists", deser);
- resolutions = make_shared_ptr(new ResolverLists(ResolverLists::deserialise(desern)));
+ resolved = make_shared_ptr(new Resolved(Resolved::deserialise(desern)));
}
- {
- TestMessageSuffix s("taken errors");
- check_resolution_list(resolutions->jobs(), resolutions->taken_error_job_ids(), ResolutionListChecks()
- .kind("unable_to_make_decision", QualifiedPackageName("serialisation/error"))
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("untaken errors");
- check_resolution_list(resolutions->jobs(), resolutions->untaken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("ordered");
- check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
- .qpn(QualifiedPackageName("serialisation/dep"))
- .qpn(QualifiedPackageName("serialisation/target"))
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("untaken");
- check_resolution_list(resolutions->jobs(), resolutions->untaken_job_ids(), ResolutionListChecks()
- .qpn(QualifiedPackageName("serialisation/suggestion"))
- .finished()
- );
- }
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .change(QualifiedPackageName("serialisation/dep"))
+ .change(QualifiedPackageName("serialisation/target"))
+ .finished()),
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .unable(QualifiedPackageName("serialisation/error"))
+ .finished()),
+ n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .change(QualifiedPackageName("serialisation/suggestion"))
+ .finished()),
+ n::untaken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished())
+ );
}
} test_serialisation;
}
diff --git a/paludis/resolver/resolver_TEST_simple.cc b/paludis/resolver/resolver_TEST_simple.cc
index 81bfea0..b96865d 100644
--- a/paludis/resolver/resolver_TEST_simple.cc
+++ b/paludis/resolver/resolver_TEST_simple.cc
@@ -21,11 +21,9 @@
#include <paludis/resolver/resolver_functions.hh>
#include <paludis/resolver/resolution.hh>
#include <paludis/resolver/decision.hh>
-#include <paludis/resolver/resolutions.hh>
#include <paludis/resolver/constraint.hh>
#include <paludis/resolver/resolvent.hh>
#include <paludis/resolver/suggest_restart.hh>
-#include <paludis/resolver/resolver_lists.hh>
#include <paludis/environments/test/test_environment.hh>
#include <paludis/util/make_named_values.hh>
#include <paludis/util/options.hh>
@@ -35,6 +33,7 @@
#include <paludis/util/map.hh>
#include <paludis/util/indirect_iterator-impl.hh>
#include <paludis/util/accept_visitor.hh>
+#include <paludis/util/make_shared_copy.hh>
#include <paludis/user_dep_spec.hh>
#include <paludis/repository_factory.hh>
#include <paludis/package_database.hh>
@@ -72,30 +71,18 @@ namespace test_cases
void run()
{
- std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("no-deps/target"));
-
- {
- TestMessageSuffix s("taken errors");
- check_resolution_list(resolutions->jobs(), resolutions->taken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("untaken errors");
- check_resolution_list(resolutions->jobs(), resolutions->untaken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
-
- {
- TestMessageSuffix s("ordered");
- check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
- .qpn(QualifiedPackageName("no-deps/target"))
- .finished()
- );
- }
+ std::tr1::shared_ptr<const Resolved> resolved(get_resolved("no-deps/target"));
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .change(QualifiedPackageName("no-deps/target"))
+ .finished()),
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished())
+ );
}
} test_no_deps;
@@ -105,34 +92,73 @@ namespace test_cases
void run()
{
- std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("build-deps/target"));
-
- {
- TestMessageSuffix s("taken errors");
- check_resolution_list(resolutions->jobs(), resolutions->taken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("untaken errors");
- check_resolution_list(resolutions->jobs(), resolutions->untaken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
-
- {
- TestMessageSuffix s("ordered");
- check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
- .qpn(QualifiedPackageName("build-deps/a-dep"))
- .qpn(QualifiedPackageName("build-deps/b-dep"))
- .qpn(QualifiedPackageName("build-deps/z-dep"))
- .qpn(QualifiedPackageName("build-deps/target"))
- .finished()
- );
- }
+ std::tr1::shared_ptr<const Resolved> resolved(get_resolved("build-deps/target"));
+
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .change(QualifiedPackageName("build-deps/a-dep"))
+ .change(QualifiedPackageName("build-deps/b-dep"))
+ .change(QualifiedPackageName("build-deps/z-dep"))
+ .change(QualifiedPackageName("build-deps/target"))
+ .finished()),
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished())
+ );
}
} test_build_deps;
+
+ struct TestRunDeps : ResolverSimpleTestCase
+ {
+ TestRunDeps() : ResolverSimpleTestCase("run-deps") { }
+
+ void run()
+ {
+ std::tr1::shared_ptr<const Resolved> resolved(get_resolved("run-deps/target"));
+
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .change(QualifiedPackageName("run-deps/a-dep"))
+ .change(QualifiedPackageName("run-deps/b-dep"))
+ .change(QualifiedPackageName("run-deps/z-dep"))
+ .change(QualifiedPackageName("run-deps/target"))
+ .finished()),
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished())
+ );
+ }
+ } test_run_deps;
+
+ struct TestPostDeps : ResolverSimpleTestCase
+ {
+ TestPostDeps() : ResolverSimpleTestCase("post-deps") { }
+
+ void run()
+ {
+ std::tr1::shared_ptr<const Resolved> resolved(get_resolved("post-deps/target"));
+
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .change(QualifiedPackageName("post-deps/a-dep"))
+ .change(QualifiedPackageName("post-deps/b-dep"))
+ .change(QualifiedPackageName("post-deps/target"))
+ .change(QualifiedPackageName("post-deps/z-dep"))
+ .finished()),
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished())
+ );
+ }
+ } test_post_deps;
}
diff --git a/paludis/resolver/resolver_TEST_simple_setup.sh b/paludis/resolver/resolver_TEST_simple_setup.sh
index c025889..4c9d0aa 100755
--- a/paludis/resolver/resolver_TEST_simple_setup.sh
+++ b/paludis/resolver/resolver_TEST_simple_setup.sh
@@ -60,5 +60,75 @@ SLOT="0"
DEPENDENCIES=""
END
+# run-deps
+echo 'run-deps' >> metadata/categories.conf
+
+mkdir -p 'packages/run-deps/target'
+cat <<END > packages/run-deps/target/target-1.exheres-0
+SUMMARY="target"
+PLATFORMS="test"
+SLOT="0"
+DEPENDENCIES="run: run-deps/a-dep run-deps/b-dep run-deps/z-dep"
+END
+
+mkdir -p 'packages/run-deps/a-dep'
+cat <<END > packages/run-deps/a-dep/a-dep-1.exheres-0
+SUMMARY="target"
+PLATFORMS="test"
+SLOT="0"
+DEPENDENCIES=""
+END
+
+mkdir -p 'packages/run-deps/b-dep'
+cat <<END > packages/run-deps/b-dep/b-dep-1.exheres-0
+SUMMARY="target"
+PLATFORMS="test"
+SLOT="0"
+DEPENDENCIES=""
+END
+
+mkdir -p 'packages/run-deps/z-dep'
+cat <<END > packages/run-deps/z-dep/z-dep-1.exheres-0
+SUMMARY="target"
+PLATFORMS="test"
+SLOT="0"
+DEPENDENCIES=""
+END
+
+# post-deps
+echo 'post-deps' >> metadata/categories.conf
+
+mkdir -p 'packages/post-deps/target'
+cat <<END > packages/post-deps/target/target-1.exheres-0
+SUMMARY="target"
+PLATFORMS="test"
+SLOT="0"
+DEPENDENCIES="post: post-deps/a-dep post-deps/b-dep post-deps/z-dep"
+END
+
+mkdir -p 'packages/post-deps/a-dep'
+cat <<END > packages/post-deps/a-dep/a-dep-1.exheres-0
+SUMMARY="target"
+PLATFORMS="test"
+SLOT="0"
+DEPENDENCIES=""
+END
+
+mkdir -p 'packages/post-deps/b-dep'
+cat <<END > packages/post-deps/b-dep/b-dep-1.exheres-0
+SUMMARY="target"
+PLATFORMS="test"
+SLOT="0"
+DEPENDENCIES=""
+END
+
+mkdir -p 'packages/post-deps/z-dep'
+cat <<END > packages/post-deps/z-dep/z-dep-1.exheres-0
+SUMMARY="target"
+PLATFORMS="test"
+SLOT="0"
+DEPENDENCIES=""
+END
+
cd ..
diff --git a/paludis/resolver/resolver_TEST_suggestions.cc b/paludis/resolver/resolver_TEST_suggestions.cc
index 7810b1f..1fa93ee 100644
--- a/paludis/resolver/resolver_TEST_suggestions.cc
+++ b/paludis/resolver/resolver_TEST_suggestions.cc
@@ -21,11 +21,9 @@
#include <paludis/resolver/resolver_functions.hh>
#include <paludis/resolver/resolution.hh>
#include <paludis/resolver/decision.hh>
-#include <paludis/resolver/resolutions.hh>
#include <paludis/resolver/constraint.hh>
#include <paludis/resolver/resolvent.hh>
#include <paludis/resolver/suggest_restart.hh>
-#include <paludis/resolver/resolver_lists.hh>
#include <paludis/environments/test/test_environment.hh>
#include <paludis/util/make_named_values.hh>
#include <paludis/util/options.hh>
@@ -35,6 +33,7 @@
#include <paludis/util/map.hh>
#include <paludis/util/indirect_iterator-impl.hh>
#include <paludis/util/accept_visitor.hh>
+#include <paludis/util/make_shared_copy.hh>
#include <paludis/user_dep_spec.hh>
#include <paludis/repository_factory.hh>
#include <paludis/package_database.hh>
@@ -72,38 +71,20 @@ namespace test_cases
void run()
{
- std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("suggestion/target"));
-
- {
- TestMessageSuffix s("taken errors");
- check_resolution_list(resolutions->jobs(), resolutions->taken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("untaken errors");
- check_resolution_list(resolutions->jobs(), resolutions->untaken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
-
- {
- TestMessageSuffix s("ordered");
- check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
- .qpn(QualifiedPackageName("suggestion/target"))
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("untaken");
- check_resolution_list(resolutions->jobs(), resolutions->untaken_job_ids(), ResolutionListChecks()
- .qpn(QualifiedPackageName("suggestion/dep"))
- .finished()
- );
- }
+ std::tr1::shared_ptr<const Resolved> resolved(get_resolved("suggestion/target"));
+
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .change(QualifiedPackageName("suggestion/target"))
+ .finished()),
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .change(QualifiedPackageName("suggestion/dep"))
+ .finished()),
+ n::untaken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished())
+ );
}
} test_suggestion;
@@ -113,38 +94,20 @@ namespace test_cases
void run()
{
- std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("unmeetable-suggestion/target"));
-
- {
- TestMessageSuffix s("taken errors");
- check_resolution_list(resolutions->jobs(), resolutions->taken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("untaken errors");
- check_resolution_list(resolutions->jobs(), resolutions->untaken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
-
- {
- TestMessageSuffix s("ordered");
- check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
- .qpn(QualifiedPackageName("unmeetable-suggestion/target"))
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("untaken");
- check_resolution_list(resolutions->jobs(), resolutions->untaken_job_ids(), ResolutionListChecks()
- .qpn(QualifiedPackageName("unmeetable-suggestion/unmeetable-dep"))
- .finished()
- );
- }
+ std::tr1::shared_ptr<const Resolved> resolved(get_resolved("unmeetable-suggestion/target"));
+
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .change(QualifiedPackageName("unmeetable-suggestion/target"))
+ .finished()),
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .unable(QualifiedPackageName("unmeetable-suggestion/unmeetable-dep"))
+ .finished())
+ );
}
} test_unmeetable_suggestion;
@@ -154,39 +117,21 @@ namespace test_cases
void run()
{
- std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("suggestion-then-dependency/target"));
-
- {
- TestMessageSuffix s("taken errors");
- check_resolution_list(resolutions->jobs(), resolutions->taken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("untaken errors");
- check_resolution_list(resolutions->jobs(), resolutions->untaken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
-
- {
- TestMessageSuffix s("ordered");
- check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
- .qpn(QualifiedPackageName("suggestion-then-dependency/a-suggested-dep"))
- .qpn(QualifiedPackageName("suggestion-then-dependency/hard-dep"))
- .qpn(QualifiedPackageName("suggestion-then-dependency/target"))
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("untaken");
- check_resolution_list(resolutions->jobs(), resolutions->untaken_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
+ std::tr1::shared_ptr<const Resolved> resolved(get_resolved("suggestion-then-dependency/target"));
+
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .change(QualifiedPackageName("suggestion-then-dependency/a-suggested-dep"))
+ .change(QualifiedPackageName("suggestion-then-dependency/hard-dep"))
+ .change(QualifiedPackageName("suggestion-then-dependency/target"))
+ .finished()),
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished())
+ );
}
} test_suggestion_then_dependency;
}
diff --git a/paludis/resolver/resolver_TEST_suggestions_setup.sh b/paludis/resolver/resolver_TEST_suggestions_setup.sh
index d24c796..58b6695 100755
--- a/paludis/resolver/resolver_TEST_suggestions_setup.sh
+++ b/paludis/resolver/resolver_TEST_suggestions_setup.sh
@@ -50,7 +50,7 @@ END
mkdir -p 'packages/unmeetable-suggestion/unmeetable-dep'
cat <<END > packages/unmeetable-suggestion/unmeetable-dep/unmeetable-dep-1.exheres-0
SUMMARY="unmeetable dep"
-PLATFORMS="test"
+PLATFORMS=""
SLOT="0"
END
diff --git a/paludis/resolver/resolver_TEST_virtuals.cc b/paludis/resolver/resolver_TEST_virtuals.cc
index 53385b4..dfb20cb 100644
--- a/paludis/resolver/resolver_TEST_virtuals.cc
+++ b/paludis/resolver/resolver_TEST_virtuals.cc
@@ -21,11 +21,9 @@
#include <paludis/resolver/resolver_functions.hh>
#include <paludis/resolver/resolution.hh>
#include <paludis/resolver/decision.hh>
-#include <paludis/resolver/resolutions.hh>
#include <paludis/resolver/constraint.hh>
#include <paludis/resolver/resolvent.hh>
#include <paludis/resolver/suggest_restart.hh>
-#include <paludis/resolver/resolver_lists.hh>
#include <paludis/environments/test/test_environment.hh>
#include <paludis/util/make_named_values.hh>
#include <paludis/util/options.hh>
@@ -35,6 +33,7 @@
#include <paludis/util/map.hh>
#include <paludis/util/indirect_iterator-impl.hh>
#include <paludis/util/accept_visitor.hh>
+#include <paludis/util/make_shared_copy.hh>
#include <paludis/user_dep_spec.hh>
#include <paludis/repository_factory.hh>
#include <paludis/package_database.hh>
@@ -72,37 +71,20 @@ namespace test_cases
void run()
{
- std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("virtuals/target"));
-
- {
- TestMessageSuffix s("taken errors");
- check_resolution_list(resolutions->jobs(), resolutions->taken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("untaken errors");
- check_resolution_list(resolutions->jobs(), resolutions->untaken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("ordered");
- check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
- .qpn(QualifiedPackageName("cat/foo-a"))
- .qpn(QualifiedPackageName("virtuals/target"))
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("untaken");
- check_resolution_list(resolutions->jobs(), resolutions->untaken_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
+ std::tr1::shared_ptr<const Resolved> resolved(get_resolved("virtuals/target"));
+
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .change(QualifiedPackageName("cat/foo-a"))
+ .change(QualifiedPackageName("virtuals/target"))
+ .finished()),
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished())
+ );
}
} test_virtuals;
@@ -112,36 +94,19 @@ namespace test_cases
void run()
{
- std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("virtual/virtual-target"));
-
- {
- TestMessageSuffix s("taken errors");
- check_resolution_list(resolutions->jobs(), resolutions->taken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("untaken errors");
- check_resolution_list(resolutions->jobs(), resolutions->untaken_error_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("ordered");
- check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
- .qpn(QualifiedPackageName("cat/real-target"))
- .finished()
- );
- }
-
- {
- TestMessageSuffix s("untaken");
- check_resolution_list(resolutions->jobs(), resolutions->untaken_job_ids(), ResolutionListChecks()
- .finished()
- );
- }
+ std::tr1::shared_ptr<const Resolved> resolved(get_resolved("virtual/virtual-target"));
+
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .change(QualifiedPackageName("cat/real-target"))
+ .finished()),
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished())
+ );
}
} test_virtuals_target;
}
diff --git a/paludis/resolver/resolver_functions.hh b/paludis/resolver/resolver_functions.hh
index 08c8661..8ccc281 100644
--- a/paludis/resolver/resolver_functions.hh
+++ b/paludis/resolver/resolver_functions.hh
@@ -71,19 +71,16 @@ namespace paludis
)> AllowedToRemoveFunction;
typedef std::tr1::function<bool (
- const Resolvent &,
const std::tr1::shared_ptr<const Resolution> &,
const std::tr1::shared_ptr<const RequiredConfirmation> &
)> ConfirmFunction;
typedef std::tr1::function<const std::tr1::shared_ptr<const Repository> (
- const Resolvent &,
const std::tr1::shared_ptr<const Resolution> &,
const ChangesToMakeDecision &
)> FindRepositoryForFunction;
typedef std::tr1::function<std::tr1::shared_ptr<ConstraintSequence> (
- const Resolvent &,
const std::tr1::shared_ptr<const Resolution> &,
const std::tr1::shared_ptr<const PackageID> &,
const std::tr1::shared_ptr<const PackageIDSequence> &
@@ -106,13 +103,12 @@ namespace paludis
)> GetResolventsForFunction;
typedef std::tr1::function<UseExisting (
- const Resolvent &,
+ const std::tr1::shared_ptr<const Resolution> &,
const PackageDepSpec &,
const std::tr1::shared_ptr<const Reason> &
)> GetUseExistingFunction;
typedef std::tr1::function<SpecInterest (
- const Resolvent &,
const std::tr1::shared_ptr<const Resolution> &,
const SanitisedDependency &
)> InterestInSpecFunction;
diff --git a/paludis/resolver/resolver_lists.cc b/paludis/resolver/resolver_lists.cc
deleted file mode 100644
index e5752b3..0000000
--- a/paludis/resolver/resolver_lists.cc
+++ /dev/null
@@ -1,96 +0,0 @@
-/* vim: set sw=4 sts=4 et foldmethod=syntax : */
-
-/*
- * Copyright (c) 2009, 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 <paludis/resolver/resolver_lists.hh>
-#include <paludis/resolver/resolutions.hh>
-#include <paludis/resolver/jobs.hh>
-#include <paludis/resolver/job_id.hh>
-#include <paludis/util/sequence.hh>
-#include <paludis/util/make_named_values.hh>
-#include <paludis/util/wrapped_forward_iterator.hh>
-#include <paludis/serialise-impl.hh>
-
-using namespace paludis;
-using namespace paludis::resolver;
-
-void
-ResolverLists::serialise(Serialiser & s) const
-{
- s.object("ResolverLists")
- .member(SerialiserFlags<serialise::might_be_null>(), "all_resolutions", all_resolutions())
- .member(SerialiserFlags<serialise::might_be_null>(), "jobs", jobs())
- .member(SerialiserFlags<serialise::container, serialise::might_be_null>(), "job_ids_needing_confirmation", job_ids_needing_confirmation())
- .member(SerialiserFlags<serialise::container, serialise::might_be_null>(), "taken_error_job_ids", taken_error_job_ids())
- .member(SerialiserFlags<serialise::container, serialise::might_be_null>(), "taken_job_ids", taken_job_ids())
- .member(SerialiserFlags<serialise::container, serialise::might_be_null>(), "untaken_error_job_ids", untaken_error_job_ids())
- .member(SerialiserFlags<serialise::container, serialise::might_be_null>(), "untaken_job_ids", untaken_job_ids())
- ;
-}
-
-const ResolverLists
-ResolverLists::deserialise(Deserialisation & d)
-{
- Deserialisator v(d, "ResolverLists");
-
- std::tr1::shared_ptr<JobIDSequence> job_ids_needing_confirmation(new JobIDSequence);
- {
- Deserialisator vv(*v.find_remove_member("job_ids_needing_confirmation"), "c");
- for (int n(1), n_end(vv.member<int>("count") + 1) ; n != n_end ; ++n)
- job_ids_needing_confirmation->push_back(vv.member<JobID>(stringify(n)));
- }
-
- std::tr1::shared_ptr<JobIDSequence> taken_error_job_ids(new JobIDSequence);
- {
- Deserialisator vv(*v.find_remove_member("taken_error_job_ids"), "c");
- for (int n(1), n_end(vv.member<int>("count") + 1) ; n != n_end ; ++n)
- taken_error_job_ids->push_back(vv.member<JobID>(stringify(n)));
- }
-
- std::tr1::shared_ptr<JobIDSequence> taken_job_ids(new JobIDSequence);
- {
- Deserialisator vv(*v.find_remove_member("taken_job_ids"), "c");
- for (int n(1), n_end(vv.member<int>("count") + 1) ; n != n_end ; ++n)
- taken_job_ids->push_back(vv.member<JobID>(stringify(n)));
- }
-
- std::tr1::shared_ptr<JobIDSequence> untaken_error_job_ids(new JobIDSequence);
- {
- Deserialisator vv(*v.find_remove_member("untaken_error_job_ids"), "c");
- for (int n(1), n_end(vv.member<int>("count") + 1) ; n != n_end ; ++n)
- untaken_error_job_ids->push_back(vv.member<JobID>(stringify(n)));
- }
-
- std::tr1::shared_ptr<JobIDSequence> untaken_job_ids(new JobIDSequence);
- {
- Deserialisator vv(*v.find_remove_member("untaken_job_ids"), "c");
- for (int n(1), n_end(vv.member<int>("count") + 1) ; n != n_end ; ++n)
- untaken_job_ids->push_back(vv.member<JobID>(stringify(n)));
- }
-
- return make_named_values<ResolverLists>(
- n::all_resolutions() = v.member<std::tr1::shared_ptr<Resolutions> >("all_resolutions"),
- n::job_ids_needing_confirmation() = job_ids_needing_confirmation,
- n::jobs() = v.member<std::tr1::shared_ptr<Jobs> >("jobs"),
- n::taken_error_job_ids() = taken_error_job_ids,
- n::taken_job_ids() = taken_job_ids,
- n::untaken_error_job_ids() = untaken_error_job_ids,
- n::untaken_job_ids() = untaken_job_ids
- );
-}
-
diff --git a/paludis/resolver/resolver_lists.hh b/paludis/resolver/resolver_lists.hh
deleted file mode 100644
index 75b913e..0000000
--- a/paludis/resolver/resolver_lists.hh
+++ /dev/null
@@ -1,62 +0,0 @@
-/* vim: set sw=4 sts=4 et foldmethod=syntax : */
-
-/*
- * Copyright (c) 2009, 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_PALUDIS_RESOLVER_RESOLVER_LISTS_HH
-#define PALUDIS_GUARD_PALUDIS_RESOLVER_RESOLVER_LISTS_HH 1
-
-#include <paludis/resolver/resolver_lists-fwd.hh>
-#include <paludis/resolver/resolutions-fwd.hh>
-#include <paludis/resolver/job_id-fwd.hh>
-#include <paludis/resolver/jobs-fwd.hh>
-#include <paludis/util/named_value.hh>
-#include <paludis/serialise.hh>
-#include <tr1/memory>
-
-namespace paludis
-{
- namespace n
- {
- typedef Name<struct all_resolutions_name> all_resolutions;
- typedef Name<struct job_ids_needing_confirmation_name> job_ids_needing_confirmation;
- typedef Name<struct jobs_name> jobs;
- typedef Name<struct taken_error_job_ids_name> taken_error_job_ids;
- typedef Name<struct taken_job_ids_name> taken_job_ids;
- typedef Name<struct untaken_error_job_ids_name> untaken_error_job_ids;
- typedef Name<struct untaken_job_ids_name> untaken_job_ids;
- }
-
- namespace resolver
- {
- struct ResolverLists
- {
- NamedValue<n::all_resolutions, std::tr1::shared_ptr<Resolutions> > all_resolutions;
- NamedValue<n::job_ids_needing_confirmation, std::tr1::shared_ptr<JobIDSequence> > job_ids_needing_confirmation;
- NamedValue<n::jobs, std::tr1::shared_ptr<Jobs> > jobs;
- NamedValue<n::taken_error_job_ids, std::tr1::shared_ptr<JobIDSequence> > taken_error_job_ids;
- NamedValue<n::taken_job_ids, std::tr1::shared_ptr<JobIDSequence> > taken_job_ids;
- NamedValue<n::untaken_error_job_ids, std::tr1::shared_ptr<JobIDSequence> > untaken_error_job_ids;
- NamedValue<n::untaken_job_ids, std::tr1::shared_ptr<JobIDSequence> > untaken_job_ids;
-
- static const ResolverLists deserialise(Deserialisation &) PALUDIS_ATTRIBUTE((warn_unused_result));
- void serialise(Serialiser &) const;
- };
- }
-}
-
-#endif
diff --git a/paludis/resolver/resolver_test.cc b/paludis/resolver/resolver_test.cc
index b12b251..456a1f7 100644
--- a/paludis/resolver/resolver_test.cc
+++ b/paludis/resolver/resolver_test.cc
@@ -22,15 +22,11 @@
#include <paludis/resolver/resolvent.hh>
#include <paludis/resolver/resolver.hh>
#include <paludis/resolver/resolution.hh>
-#include <paludis/resolver/resolutions.hh>
#include <paludis/resolver/resolver_functions.hh>
#include <paludis/resolver/suggest_restart.hh>
#include <paludis/resolver/decision.hh>
+#include <paludis/resolver/decisions.hh>
#include <paludis/resolver/decider.hh>
-#include <paludis/resolver/orderer.hh>
-#include <paludis/resolver/job.hh>
-#include <paludis/resolver/jobs.hh>
-#include <paludis/resolver/job_id.hh>
#include <paludis/resolver/reason.hh>
#include <paludis/util/map.hh>
#include <paludis/util/make_shared_ptr.hh>
@@ -41,6 +37,7 @@
#include <paludis/util/make_shared_copy.hh>
#include <paludis/util/set-impl.hh>
#include <paludis/util/tribool.hh>
+#include <paludis/util/simple_visitor_cast.hh>
#include <paludis/repositories/fake/fake_installed_repository.hh>
#include <paludis/repository_factory.hh>
#include <paludis/package_database.hh>
@@ -216,7 +213,7 @@ paludis::resolver::resolver_test::is_just_suggestion(const SanitisedDependency &
SpecInterest
paludis::resolver::resolver_test::interest_in_spec_fn(
- const Resolvent &, const std::tr1::shared_ptr<const Resolution> &, const SanitisedDependency & dep)
+ const std::tr1::shared_ptr<const Resolution> &, const SanitisedDependency & dep)
{
if (is_just_suggestion(dep))
return si_untaken;
@@ -226,7 +223,7 @@ paludis::resolver::resolver_test::interest_in_spec_fn(
UseExisting
paludis::resolver::resolver_test::get_use_existing_fn(
- const Resolvent &,
+ const std::tr1::shared_ptr<const Resolution> &,
const PackageDepSpec &,
const std::tr1::shared_ptr<const Reason> &)
{
@@ -236,7 +233,6 @@ paludis::resolver::resolver_test::get_use_existing_fn(
const std::tr1::shared_ptr<const Repository>
paludis::resolver::resolver_test::find_repository_for_fn(
const Environment * const env,
- const Resolvent &,
const std::tr1::shared_ptr<const Resolution> &,
const ChangesToMakeDecision &)
{
@@ -281,7 +277,6 @@ paludis::resolver::resolver_test::prefer_or_avoid_fn(
bool
paludis::resolver::resolver_test::confirm_fn(
- const Resolvent &,
const std::tr1::shared_ptr<const Resolution> &,
const std::tr1::shared_ptr<const RequiredConfirmation> &)
{
@@ -290,7 +285,6 @@ paludis::resolver::resolver_test::confirm_fn(
const std::tr1::shared_ptr<ConstraintSequence>
paludis::resolver::resolver_test::get_constraints_for_dependent_fn(
- const Resolvent &,
const std::tr1::shared_ptr<const Resolution> &,
const std::tr1::shared_ptr<const PackageID> & id,
const std::tr1::shared_ptr<const PackageIDSequence> & ids)
@@ -380,8 +374,7 @@ ResolverTestCase::get_resolver_functions(InitialConstraints & initial_constraint
allowed_to_remove_names, std::tr1::placeholders::_1),
n::confirm_fn() = &confirm_fn,
n::find_repository_for_fn() = std::tr1::bind(&find_repository_for_fn,
- &env, std::tr1::placeholders::_1, std::tr1::placeholders::_2,
- std::tr1::placeholders::_3),
+ &env, std::tr1::placeholders::_1, std::tr1::placeholders::_2),
n::get_constraints_for_dependent_fn() = &get_constraints_for_dependent_fn,
n::get_destination_types_for_fn() = &get_destination_types_for_fn,
n::get_initial_constraints_for_fn() =
@@ -398,8 +391,8 @@ ResolverTestCase::get_resolver_functions(InitialConstraints & initial_constraint
);
}
-const std::tr1::shared_ptr<const ResolverLists>
-ResolverTestCase::get_resolutions(const PackageOrBlockDepSpec & target)
+const std::tr1::shared_ptr<const Resolved>
+ResolverTestCase::get_resolved(const PackageOrBlockDepSpec & target)
{
InitialConstraints initial_constraints;
@@ -410,7 +403,7 @@ ResolverTestCase::get_resolutions(const PackageOrBlockDepSpec & target)
Resolver resolver(&env, get_resolver_functions(initial_constraints));
resolver.add_target(target);
resolver.resolve();
- return resolver.lists();
+ return resolver.resolved();
}
catch (const SuggestRestart & e)
{
@@ -419,264 +412,219 @@ ResolverTestCase::get_resolutions(const PackageOrBlockDepSpec & target)
}
}
-const std::tr1::shared_ptr<const ResolverLists>
-ResolverTestCase::get_resolutions(const std::string & target)
+const std::tr1::shared_ptr<const Resolved>
+ResolverTestCase::get_resolved(const std::string & target)
{
PackageDepSpec target_spec(parse_user_package_dep_spec(target, &env, UserPackageDepSpecOptions()));
- return get_resolutions(target_spec);
+ return get_resolved(target_spec);
}
namespace
{
- struct ChosenIDVisitor
+ template <typename T_>
+ std::tr1::shared_ptr<T_> get_decision(const std::tr1::shared_ptr<T_> & d)
{
- const std::tr1::shared_ptr<const PackageID> visit(const ChangesToMakeDecision & decision) const
- {
- return decision.origin_id();
- }
-
- const std::tr1::shared_ptr<const PackageID> visit(const ExistingNoChangeDecision & decision) const
- {
- return decision.existing_id();
- }
-
- const std::tr1::shared_ptr<const PackageID> visit(const RemoveDecision &) const
- {
- return make_null_shared_ptr();
- }
+ return d;
+ }
- const std::tr1::shared_ptr<const PackageID> visit(const NothingNoChangeDecision &) const
- {
- return make_null_shared_ptr();
- }
+ template <typename T_, typename N_>
+ std::tr1::shared_ptr<T_> get_decision(const std::pair<std::tr1::shared_ptr<T_>, N_> & d)
+ {
+ return d.first;
+ }
+}
- const std::tr1::shared_ptr<const PackageID> visit(const UnableToMakeDecision &) const
- {
- return make_null_shared_ptr();
- }
- };
+template <typename Decisions_>
+void
+ResolverTestCase::check_resolved_one(
+ const std::tr1::shared_ptr<Decisions_> & decisions,
+ const std::tr1::shared_ptr<const DecisionChecks> & decision_checks)
+{
+ DecisionChecks::List::const_iterator decision_check(decision_checks->checks.begin()), decision_check_end(decision_checks->checks.end());
+ typename Decisions_::ConstIterator decision(decisions->begin()), decision_end(decisions->end());
- struct KindNameVisitor
+ while (true)
{
- const std::string visit(const UnableToMakeDecision &) const
- {
- return "unable_to_make_decision";
- }
-
- const std::string visit(const RemoveDecision &) const
- {
- return "remove_decision";
- }
+ if (decision_check == decision_check_end)
+ break;
- const std::string visit(const NothingNoChangeDecision &) const
- {
- return "nothing_no_change";
- }
+ std::tr1::shared_ptr<const Decision> d;
+ if (decision != decision_end)
+ d = get_decision(*decision++);
- const std::string visit(const ExistingNoChangeDecision &) const
- {
- return "existing_no_change";
- }
+ TEST_CHECK_MESSAGE(decision_check->first(d), decision_check->second(d));
+ ++decision_check;
+ }
- const std::string visit(const ChangesToMakeDecision &) const
- {
- return "changes_to_make";
- }
- };
+ TEST_CHECK(decision_check == decision_check_end);
+ TEST_CHECK(decision == decision_end);
}
-bool
-ResolverTestCase::ResolutionListChecks::check_qpn(const QualifiedPackageName & q, const std::tr1::shared_ptr<const Resolution> & r)
+void
+ResolverTestCase::check_resolved(
+ const std::tr1::shared_ptr<const Resolved> & resolved,
+ const NamedValue<n::taken_change_or_remove_decisions, const std::tr1::shared_ptr<const DecisionChecks> > & taken_change_or_remove_decisions,
+ const NamedValue<n::taken_unable_to_make_decisions, const std::tr1::shared_ptr<const DecisionChecks> > & taken_unable_to_make_decisions,
+ const NamedValue<n::untaken_change_or_remove_decisions, const std::tr1::shared_ptr<const DecisionChecks> > & untaken_change_or_remove_decisions,
+ const NamedValue<n::untaken_unable_to_make_decisions, const std::tr1::shared_ptr<const DecisionChecks> > & untaken_unable_to_make_decisions
+ )
{
- if ((! r) || (! r->decision()))
- return false;
+ {
+ TestMessageSuffix s("taken change or remove");
+ check_resolved_one(resolved->taken_change_or_remove_decisions(), taken_change_or_remove_decisions());
+ }
- const std::tr1::shared_ptr<const PackageID> id(r->decision()->accept_returning<
- std::tr1::shared_ptr<const PackageID> >(ChosenIDVisitor()));
- if (! id)
- return false;
+ {
+ TestMessageSuffix s("taken unable to make");
+ check_resolved_one(resolved->taken_unable_to_make_decisions(), taken_unable_to_make_decisions());
+ }
+
+ {
+ TestMessageSuffix s("untaken change or remove");
+ check_resolved_one(resolved->untaken_change_or_remove_decisions(), untaken_change_or_remove_decisions());
+ }
- return id->name() == q;
+ {
+ TestMessageSuffix s("untaken unable to make");
+ check_resolved_one(resolved->untaken_unable_to_make_decisions(), untaken_unable_to_make_decisions());
+ }
}
-bool
-ResolverTestCase::ResolutionListChecks::check_kind(const std::string & k,
- const QualifiedPackageName & q, const std::tr1::shared_ptr<const Resolution> & r)
+ResolverTestCase::DecisionChecks &
+ResolverTestCase::DecisionChecks::finished()
{
- if ((! r) || (! r->decision()))
- return false;
-
- return r->decision()->accept_returning<std::string>(KindNameVisitor()) == k && r->resolvent().package() == q;
+ checks.push_back(std::make_pair(
+ &check_finished,
+ &check_finished_msg
+ ));
+ return *this;
}
-std::string
-ResolverTestCase::ResolutionListChecks::check_kind_msg(const std::string & k,
- const QualifiedPackageName & q, const std::tr1::shared_ptr<const Resolution> & r)
+ResolverTestCase::DecisionChecks &
+ResolverTestCase::DecisionChecks::change(const QualifiedPackageName & q)
{
- if (! r)
- return "Expected " + stringify(k) + " " + stringify(q) + " but got finished";
- else if (! r->decision())
- return "Expected " + stringify(k) + " " + stringify(q) + " but got undecided for " + stringify(r->resolvent());
- else
- return "Expected " + stringify(k) + " " + stringify(q) + " but got "
- + r->decision()->accept_returning<std::string>(KindNameVisitor()) + " "
- + stringify(r->resolvent().package());
+ checks.push_back(std::make_pair(
+ std::tr1::bind(&check_change, q, std::tr1::placeholders::_1),
+ std::tr1::bind(&check_change_msg, q, std::tr1::placeholders::_1)
+ ));
+ return *this;
}
-std::string
-ResolverTestCase::ResolutionListChecks::check_generic_msg(const std::string & q, const std::tr1::shared_ptr<const Resolution> & r)
+ResolverTestCase::DecisionChecks &
+ResolverTestCase::DecisionChecks::remove(const QualifiedPackageName & q)
{
- if (! r)
- return "Expected " + stringify(q) + " but got finished";
- else if (! r->decision())
- return "Expected " + stringify(q) + " but got undecided for " + stringify(r->resolvent());
- else if (! r->decision()->accept_returning<std::tr1::shared_ptr<const PackageID> >(ChosenIDVisitor()))
- return "Expected " + stringify(q) + " but got decided nothing (kind "
- + stringify(r->decision()->accept_returning<std::string>(KindNameVisitor())) + ") for "
- + stringify(r->resolvent());
- else
- return "Expected " + stringify(q) + " but got " + stringify(
- r->decision()->accept_returning<std::tr1::shared_ptr<const PackageID> >(
- ChosenIDVisitor())->name()) + " for "
- + stringify(r->resolvent());
+ checks.push_back(std::make_pair(
+ std::tr1::bind(&check_remove, q, std::tr1::placeholders::_1),
+ std::tr1::bind(&check_remove_msg, q, std::tr1::placeholders::_1)
+ ));
+ return *this;
}
-std::string
-ResolverTestCase::ResolutionListChecks::check_qpn_msg(const QualifiedPackageName & q, const std::tr1::shared_ptr<const Resolution> & r)
+ResolverTestCase::DecisionChecks &
+ResolverTestCase::DecisionChecks::unable(const QualifiedPackageName & q)
{
- return check_generic_msg(stringify(q), r);
+ checks.push_back(std::make_pair(
+ std::tr1::bind(&check_unable, q, std::tr1::placeholders::_1),
+ std::tr1::bind(&check_unable_msg, q, std::tr1::placeholders::_1)
+ ));
+ return *this;
}
bool
-ResolverTestCase::ResolutionListChecks::check_finished(const std::tr1::shared_ptr<const Resolution> & r)
+ResolverTestCase::DecisionChecks::check_finished(const std::tr1::shared_ptr<const Decision> & r)
{
return ! r;
}
std::string
-ResolverTestCase::ResolutionListChecks::check_finished_msg(const std::tr1::shared_ptr<const Resolution> & r)
+ResolverTestCase::DecisionChecks::check_finished_msg(const std::tr1::shared_ptr<const Decision> & r)
{
return check_generic_msg("finished", r);
}
-ResolverTestCase::ResolutionListChecks &
-ResolverTestCase::ResolutionListChecks::qpn(const QualifiedPackageName & q)
+bool
+ResolverTestCase::DecisionChecks::check_change(const QualifiedPackageName & q, const std::tr1::shared_ptr<const Decision> & d)
{
- checks.push_back(std::make_pair(
- std::tr1::bind(&check_qpn, q, std::tr1::placeholders::_1),
- std::tr1::bind(&check_qpn_msg, q, std::tr1::placeholders::_1)
- ));
- return *this;
+ if (! d)
+ return false;
+
+ return simple_visitor_cast<const ChangesToMakeDecision>(*d) && d->resolvent().package() == q;
}
-ResolverTestCase::ResolutionListChecks &
-ResolverTestCase::ResolutionListChecks::kind(const std::string & k, const QualifiedPackageName & q)
+bool
+ResolverTestCase::DecisionChecks::check_remove(const QualifiedPackageName & q, const std::tr1::shared_ptr<const Decision> & d)
{
- checks.push_back(std::make_pair(
- std::tr1::bind(&check_kind, k, q, std::tr1::placeholders::_1),
- std::tr1::bind(&check_kind_msg, k, q, std::tr1::placeholders::_1)
- ));
- return *this;
+ if (! d)
+ return false;
+
+ return simple_visitor_cast<const RemoveDecision>(*d) && d->resolvent().package() == q;
}
-ResolverTestCase::ResolutionListChecks &
-ResolverTestCase::ResolutionListChecks::finished()
+bool
+ResolverTestCase::DecisionChecks::check_unable(const QualifiedPackageName & q, const std::tr1::shared_ptr<const Decision> & d)
{
- checks.push_back(std::make_pair(
- &check_finished,
- &check_finished_msg
- ));
- return *this;
+ if (! d)
+ return false;
+
+ return simple_visitor_cast<const UnableToMakeDecision>(*d) && d->resolvent().package() == q;
}
-namespace
+std::string
+ResolverTestCase::DecisionChecks::check_change_msg(const QualifiedPackageName & q, const std::tr1::shared_ptr<const Decision> & r)
{
- template <typename T_>
- struct CheckLists;
+ return check_generic_msg(stringify(q), r);
+}
- template <>
- struct CheckLists<std::tr1::shared_ptr<Resolutions> >
- {
- typedef Resolutions Type;
+std::string
+ResolverTestCase::DecisionChecks::check_remove_msg(const QualifiedPackageName & q, const std::tr1::shared_ptr<const Decision> & r)
+{
+ return check_generic_msg("remove " + stringify(q), r);
+}
- static const std::tr1::shared_ptr<const Resolution> get_resolution(
- const std::tr1::shared_ptr<const Jobs> &,
- const std::tr1::shared_ptr<const Resolution> & r)
- {
- return r;
- }
- };
+std::string
+ResolverTestCase::DecisionChecks::check_unable_msg(const QualifiedPackageName & q, const std::tr1::shared_ptr<const Decision> & r)
+{
+ return check_generic_msg("unable " + stringify(q), r);
+}
- struct InstallJobResolution
+namespace
+{
+ struct DecisionStringifier
{
- std::tr1::shared_ptr<const Resolution> visit(const UsableJob &) const
- {
- return make_null_shared_ptr();
- }
-
- std::tr1::shared_ptr<const Resolution> visit(const UsableGroupJob &) const
+ std::string visit(const NothingNoChangeDecision &) const
{
- return make_null_shared_ptr();
+ return "NothingNoChangeDecision";
}
- std::tr1::shared_ptr<const Resolution> visit(const FetchJob &) const
+ std::string visit(const UnableToMakeDecision & d) const
{
- return make_null_shared_ptr();
+ return "UnableToMakeDecision(" + stringify(d.resolvent()) + ")";
}
- std::tr1::shared_ptr<const Resolution> visit(const ErrorJob & j) const
+ std::string visit(const ChangesToMakeDecision & d) const
{
- return j.resolution();
+ return "ChangesToMakeDecision(" + stringify(*d.origin_id()) + ")";
}
- std::tr1::shared_ptr<const Resolution> visit(const SimpleInstallJob & j) const
+ std::string visit(const ExistingNoChangeDecision &) const
{
- return j.resolution();
+ return "ExistingNoChangeDecision";
}
- std::tr1::shared_ptr<const Resolution> visit(const UninstallJob & j) const
+ std::string visit(const RemoveDecision &) const
{
- return j.resolution();
- }
- };
-
- template <>
- struct CheckLists<std::tr1::shared_ptr<JobIDSequence> >
- {
- typedef JobIDSequence Type;
-
- static const std::tr1::shared_ptr<const Resolution> get_resolution(
- const std::tr1::shared_ptr<const Jobs> & jobs,
- const JobID & j)
- {
- return jobs->fetch(j)->accept_returning<std::tr1::shared_ptr<const Resolution> >(InstallJobResolution());
+ return "RemoveDecision";
}
};
}
-template <typename List_>
-void
-ResolverTestCase::check_resolution_list(
- const std::tr1::shared_ptr<const Jobs> & jobs,
- const List_ & list, const ResolutionListChecks & checks)
+std::string
+ResolverTestCase::DecisionChecks::check_generic_msg(const std::string & q, const std::tr1::shared_ptr<const Decision> & r)
{
- typename CheckLists<List_>::Type::ConstIterator r(list->begin()), r_end(list->end());
- ResolutionListChecks::List::const_iterator c(checks.checks.begin()), c_end(checks.checks.end());
- while (true)
- {
- std::tr1::shared_ptr<const Resolution> rn;
- while ((! rn) && (r != r_end))
- rn = CheckLists<List_>::get_resolution(jobs, *r++);
-
- if (c == c_end)
- break;
-
- TEST_CHECK_MESSAGE(c->first(rn), c->second(rn));
- ++c;
- }
-
- TEST_CHECK(r == r_end);
- TEST_CHECK(c == c_end);
+ if (! r)
+ return "Expected " + stringify(q) + " but got finished";
+ else
+ return "Expected " + stringify(q) + " but got " + r->accept_returning<std::string>(DecisionStringifier());
}
const std::tr1::shared_ptr<FakePackageID>
@@ -685,8 +633,3 @@ ResolverTestCase::install(const std::string & c, const std::string & p, const st
return fake_inst_repo->add_version(c, p, v);
}
-template void ResolverTestCase::check_resolution_list(const std::tr1::shared_ptr<const Jobs> &,
- const std::tr1::shared_ptr<Resolutions> &, const ResolutionListChecks &);
-template void ResolverTestCase::check_resolution_list(const std::tr1::shared_ptr<const Jobs> &,
- const std::tr1::shared_ptr<JobIDSequence> &, const ResolutionListChecks &);
-
diff --git a/paludis/resolver/resolver_test.hh b/paludis/resolver/resolver_test.hh
index 589f6e7..4693ea7 100644
--- a/paludis/resolver/resolver_test.hh
+++ b/paludis/resolver/resolver_test.hh
@@ -26,14 +26,13 @@
#include <paludis/resolver/sanitised_dependencies-fwd.hh>
#include <paludis/resolver/reason-fwd.hh>
#include <paludis/resolver/use_existing-fwd.hh>
-#include <paludis/resolver/resolutions-fwd.hh>
#include <paludis/resolver/decision-fwd.hh>
#include <paludis/resolver/destination_types-fwd.hh>
#include <paludis/resolver/resolver-fwd.hh>
-#include <paludis/resolver/jobs-fwd.hh>
#include <paludis/resolver/resolver_functions-fwd.hh>
#include <paludis/resolver/required_confirmations-fwd.hh>
#include <paludis/resolver/package_or_block_dep_spec-fwd.hh>
+#include <paludis/resolver/resolved-fwd.hh>
#include <paludis/repositories/fake/fake_installed_repository.hh>
#include <paludis/repositories/fake/fake_package_id.hh>
#include <paludis/environments/test/test_environment.hh>
@@ -59,7 +58,6 @@ namespace paludis
typedef std::map<Resolvent, std::tr1::shared_ptr<Constraints> > InitialConstraints;
SpecInterest interest_in_spec_fn(
- const Resolvent &,
const std::tr1::shared_ptr<const Resolution> &,
const SanitisedDependency &);
@@ -69,7 +67,6 @@ namespace paludis
const std::tr1::shared_ptr<ConstraintSequence>
get_constraints_for_dependent_fn(
- const Resolvent &,
const std::tr1::shared_ptr<const Resolution> &,
const std::tr1::shared_ptr<const PackageID> & id,
const std::tr1::shared_ptr<const PackageIDSequence> & ids);
@@ -81,13 +78,12 @@ namespace paludis
bool is_just_suggestion(const SanitisedDependency & dep);
UseExisting get_use_existing_fn(
- const Resolvent &,
+ const std::tr1::shared_ptr<const Resolution> &,
const PackageDepSpec &,
const std::tr1::shared_ptr<const Reason> &);
const std::tr1::shared_ptr<const Repository> find_repository_for_fn(
const Environment * const,
- const Resolvent &,
const std::tr1::shared_ptr<const Resolution> &,
const ChangesToMakeDecision &);
@@ -114,7 +110,6 @@ namespace paludis
const QualifiedPackageName &);
bool confirm_fn(
- const Resolvent &,
const std::tr1::shared_ptr<const Resolution> &,
const std::tr1::shared_ptr<const RequiredConfirmation> &);
@@ -131,45 +126,50 @@ namespace paludis
ResolverTestCase(const std::string & group, const std::string & test_name, const std::string & eapi,
const std::string & layout);
- const std::tr1::shared_ptr<const ResolverLists> get_resolutions(const PackageOrBlockDepSpec & target);
-
- const std::tr1::shared_ptr<const ResolverLists> get_resolutions(const std::string & target);
+ const std::tr1::shared_ptr<const Resolved> get_resolved(const PackageOrBlockDepSpec & target);
+ const std::tr1::shared_ptr<const Resolved> get_resolved(const std::string & target);
virtual ResolverFunctions get_resolver_functions(InitialConstraints &);
- struct ResolutionListChecks
+ struct DecisionChecks
{
- typedef std::tr1::function<bool (const std::tr1::shared_ptr<const Resolution> &) > CheckFunction;
- typedef std::tr1::function<std::string (const std::tr1::shared_ptr<const Resolution> &) > MessageFunction;
+ typedef std::tr1::function<bool (const std::tr1::shared_ptr<const Decision> &) > CheckFunction;
+ typedef std::tr1::function<std::string (const std::tr1::shared_ptr<const Decision> &) > MessageFunction;
typedef std::list<std::pair<CheckFunction, MessageFunction> > List;
List checks;
- static bool check_qpn(const QualifiedPackageName & q, const std::tr1::shared_ptr<const Resolution> & r);
-
- static std::string check_generic_msg(const std::string & q, const std::tr1::shared_ptr<const Resolution> & r);
-
- static std::string check_qpn_msg(const QualifiedPackageName & q, const std::tr1::shared_ptr<const Resolution> & r);
-
- static bool check_finished(const std::tr1::shared_ptr<const Resolution> & r);
-
- static std::string check_finished_msg(const std::tr1::shared_ptr<const Resolution> & r);
+ static std::string check_generic_msg(const std::string & q, const std::tr1::shared_ptr<const Decision> & r);
- static bool check_kind(const std::string & kind, const QualifiedPackageName &,
- const std::tr1::shared_ptr<const Resolution> & r);
+ static bool check_change(const QualifiedPackageName & q, const std::tr1::shared_ptr<const Decision> & r);
+ static std::string check_change_msg(const QualifiedPackageName & q, const std::tr1::shared_ptr<const Decision> & r);
- static std::string check_kind_msg(const std::string &, const QualifiedPackageName &,
- const std::tr1::shared_ptr<const Resolution> & r);
+ static bool check_remove(const QualifiedPackageName & q, const std::tr1::shared_ptr<const Decision> & r);
+ static std::string check_remove_msg(const QualifiedPackageName & q, const std::tr1::shared_ptr<const Decision> & r);
- ResolutionListChecks & qpn(const QualifiedPackageName & q);
+ static bool check_unable(const QualifiedPackageName & q, const std::tr1::shared_ptr<const Decision> & r);
+ static std::string check_unable_msg(const QualifiedPackageName & q, const std::tr1::shared_ptr<const Decision> & r);
- ResolutionListChecks & kind(const std::string & kind, const QualifiedPackageName & q);
+ static bool check_finished(const std::tr1::shared_ptr<const Decision> & r);
+ static std::string check_finished_msg(const std::tr1::shared_ptr<const Decision> & r);
- ResolutionListChecks & finished();
+ DecisionChecks & change(const QualifiedPackageName & q);
+ DecisionChecks & remove(const QualifiedPackageName & q);
+ DecisionChecks & unable(const QualifiedPackageName & q);
+ DecisionChecks & finished();
};
- template <typename List_>
- void check_resolution_list(const std::tr1::shared_ptr<const Jobs> &,
- const List_ & list, const ResolutionListChecks & checks);
+ template <typename Decisions_>
+ void check_resolved_one(
+ const std::tr1::shared_ptr<Decisions_> &,
+ const std::tr1::shared_ptr<const DecisionChecks> &);
+
+ void check_resolved(
+ const std::tr1::shared_ptr<const Resolved> &,
+ const NamedValue<n::taken_change_or_remove_decisions, const std::tr1::shared_ptr<const DecisionChecks> > &,
+ const NamedValue<n::taken_unable_to_make_decisions, const std::tr1::shared_ptr<const DecisionChecks> > &,
+ const NamedValue<n::untaken_change_or_remove_decisions, const std::tr1::shared_ptr<const DecisionChecks> > &,
+ const NamedValue<n::untaken_unable_to_make_decisions, const std::tr1::shared_ptr<const DecisionChecks> > &
+ );
const std::tr1::shared_ptr<FakePackageID> install(
const std::string & c, const std::string & p, const std::string & v);
diff --git a/paludis/resolver/sanitised_dependencies.cc b/paludis/resolver/sanitised_dependencies.cc
index c525f52..4cb4aca 100644
--- a/paludis/resolver/sanitised_dependencies.cc
+++ b/paludis/resolver/sanitised_dependencies.cc
@@ -19,7 +19,7 @@
#include <paludis/resolver/sanitised_dependencies.hh>
#include <paludis/resolver/resolver.hh>
-#include <paludis/resolver/resolvent.hh>
+#include <paludis/resolver/resolution.hh>
#include <paludis/resolver/spec_rewriter.hh>
#include <paludis/resolver/decider.hh>
#include <paludis/util/make_named_values.hh>
@@ -108,7 +108,7 @@ namespace
struct AnyDepSpecChildHandler
{
const Decider & decider;
- const Resolvent our_resolvent;
+ const std::tr1::shared_ptr<const Resolution> our_resolution;
const std::tr1::function<SanitisedDependency (const PackageOrBlockDepSpec &)> parent_make_sanitised;
bool super_complicated, nested;
@@ -118,10 +118,10 @@ namespace
bool seen_any;
- AnyDepSpecChildHandler(const Decider & r, const Resolvent & q,
+ AnyDepSpecChildHandler(const Decider & r, const std::tr1::shared_ptr<const Resolution> & q,
const std::tr1::function<SanitisedDependency (const PackageOrBlockDepSpec &)> & f) :
decider(r),
- our_resolvent(q),
+ our_resolution(q),
parent_make_sanitised(f),
super_complicated(false),
nested(false),
@@ -135,7 +135,7 @@ namespace
seen_any = true;
const std::tr1::shared_ptr<const RewrittenSpec> if_rewritten(decider.rewrite_if_special(spec,
- make_shared_copy(our_resolvent)));
+ make_shared_copy(our_resolution->resolvent())));
if (if_rewritten)
if_rewritten->as_spec_tree()->root()->accept(*this);
else
@@ -210,7 +210,7 @@ namespace
void visit(const DependencySpecTree::NodeType<AnyDepSpec>::Type & node)
{
- AnyDepSpecChildHandler h(decider, our_resolvent, parent_make_sanitised);
+ AnyDepSpecChildHandler h(decider, our_resolution, parent_make_sanitised);
std::for_each(indirect_iterator(node.begin()), indirect_iterator(node.end()), accept_visitor(h));
std::list<SanitisedDependency> l;
h.commit(
@@ -271,7 +271,7 @@ namespace
h != h_end ; ++h)
{
std::pair<AnyChildScore, OperatorScore> score(
- decider.find_any_score(our_resolvent, make_sanitised(PackageOrBlockDepSpec(*h))));
+ decider.find_any_score(our_resolution, make_sanitised(PackageOrBlockDepSpec(*h))));
if (score < worst_score)
worst_score = score;
}
@@ -295,7 +295,7 @@ namespace
struct Finder
{
const Decider & decider;
- const Resolvent our_resolvent;
+ const std::tr1::shared_ptr<const Resolution> our_resolution;
SanitisedDependencies & sanitised_dependencies;
const std::string raw_name;
const std::string human_name;
@@ -304,14 +304,14 @@ namespace
Finder(
const Decider & r,
- const Resolvent & q,
+ const std::tr1::shared_ptr<const Resolution> & q,
SanitisedDependencies & s,
const std::tr1::shared_ptr<const DependenciesLabelSequence> & l,
const std::string & rn,
const std::string & hn,
const std::string & a) :
decider(r),
- our_resolvent(q),
+ our_resolution(q),
sanitised_dependencies(s),
raw_name(rn),
human_name(hn),
@@ -324,7 +324,7 @@ namespace
void add(const SanitisedDependency & dep)
{
const std::tr1::shared_ptr<const RewrittenSpec> if_rewritten(decider.rewrite_if_special(dep.spec(),
- make_shared_copy(our_resolvent)));
+ make_shared_copy(our_resolution->resolvent())));
if (if_rewritten)
if_rewritten->as_spec_tree()->root()->accept(*this);
else
@@ -386,7 +386,7 @@ namespace
original_specs_as_string = "|| (" + v.result + " )";
}
- AnyDepSpecChildHandler h(decider, our_resolvent, std::tr1::bind(&Finder::make_sanitised, this, std::tr1::placeholders::_1));
+ AnyDepSpecChildHandler h(decider, our_resolution, std::tr1::bind(&Finder::make_sanitised, this, std::tr1::placeholders::_1));
std::for_each(indirect_iterator(node.begin()), indirect_iterator(node.end()), accept_visitor(h));
h.commit(
std::tr1::bind(&Finder::make_sanitised, this, std::tr1::placeholders::_1),
@@ -435,14 +435,14 @@ SanitisedDependencies::~SanitisedDependencies()
void
SanitisedDependencies::_populate_one(
const Decider & decider,
- const Resolvent & resolvent,
+ const std::tr1::shared_ptr<const Resolution> & resolution,
const std::tr1::shared_ptr<const PackageID> & id,
const std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> > (PackageID::* const pmf) () const
)
{
Context context("When finding dependencies for '" + stringify(*id) + "' from key '" + ((*id).*pmf)()->raw_name() + "':");
- Finder f(decider, resolvent, *this, ((*id).*pmf)()->initial_labels(), ((*id).*pmf)()->raw_name(),
+ Finder f(decider, resolution, *this, ((*id).*pmf)()->initial_labels(), ((*id).*pmf)()->raw_name(),
((*id).*pmf)()->human_name(), "");
((*id).*pmf)()->value()->root()->accept(f);
}
@@ -450,23 +450,23 @@ SanitisedDependencies::_populate_one(
void
SanitisedDependencies::populate(
const Decider & decider,
- const Resolvent & resolvent,
+ const std::tr1::shared_ptr<const Resolution> & resolution,
const std::tr1::shared_ptr<const PackageID> & id)
{
Context context("When finding dependencies for '" + stringify(*id) + "':");
if (id->dependencies_key())
- _populate_one(decider, resolvent, id, &PackageID::dependencies_key);
+ _populate_one(decider, resolution, id, &PackageID::dependencies_key);
else
{
if (id->build_dependencies_key())
- _populate_one(decider, resolvent, id, &PackageID::build_dependencies_key);
+ _populate_one(decider, resolution, id, &PackageID::build_dependencies_key);
if (id->run_dependencies_key())
- _populate_one(decider, resolvent, id, &PackageID::run_dependencies_key);
+ _populate_one(decider, resolution, id, &PackageID::run_dependencies_key);
if (id->post_dependencies_key())
- _populate_one(decider, resolvent, id, &PackageID::post_dependencies_key);
+ _populate_one(decider, resolution, id, &PackageID::post_dependencies_key);
if (id->suggested_dependencies_key())
- _populate_one(decider, resolvent, id, &PackageID::suggested_dependencies_key);
+ _populate_one(decider, resolution, id, &PackageID::suggested_dependencies_key);
}
}
diff --git a/paludis/resolver/sanitised_dependencies.hh b/paludis/resolver/sanitised_dependencies.hh
index c57b0c3..062202d 100644
--- a/paludis/resolver/sanitised_dependencies.hh
+++ b/paludis/resolver/sanitised_dependencies.hh
@@ -22,7 +22,7 @@
#include <paludis/resolver/sanitised_dependencies-fwd.hh>
#include <paludis/resolver/decider-fwd.hh>
-#include <paludis/resolver/resolvent-fwd.hh>
+#include <paludis/resolver/resolution-fwd.hh>
#include <paludis/resolver/package_or_block_dep_spec.hh>
#include <paludis/util/named_value.hh>
#include <paludis/dep_label-fwd.hh>
@@ -67,7 +67,7 @@ namespace paludis
private:
void _populate_one(
const Decider &,
- const Resolvent &,
+ const std::tr1::shared_ptr<const Resolution> &,
const std::tr1::shared_ptr<const PackageID> &,
const std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> > (PackageID::* const) () const
);
@@ -78,7 +78,7 @@ namespace paludis
void populate(
const Decider &,
- const Resolvent &,
+ const std::tr1::shared_ptr<const Resolution> &,
const std::tr1::shared_ptr<const PackageID> &);
void add(const SanitisedDependency & d);
diff --git a/paludis/resolver/arrow-fwd.hh b/paludis/resolver/strongly_connected_component-fwd.hh
index 0355e05..74cc0d6 100644
--- a/paludis/resolver/arrow-fwd.hh
+++ b/paludis/resolver/strongly_connected_component-fwd.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009 Ciaran McCreesh
+ * 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
@@ -17,20 +17,18 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef PALUDIS_GUARD_PALUDIS_RESOLVER_ARROW_FWD_HH
-#define PALUDIS_GUARD_PALUDIS_RESOLVER_ARROW_FWD_HH 1
+#ifndef PALUDIS_GUARD_PALUDIS_RESOLVER_STRONGLY_CONNECTED_COMPONENT_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_RESOLVER_STRONGLY_CONNECTED_COMPONENT_FWD_HH 1
-#include <paludis/util/attributes.hh>
#include <paludis/util/sequence-fwd.hh>
-#include <tr1/memory>
namespace paludis
{
namespace resolver
{
- struct Arrow;
+ struct StronglyConnectedComponent;
- typedef Sequence<Arrow> ArrowSequence;
+ typedef Sequence<StronglyConnectedComponent> SortedStronglyConnectedComponents;
}
}
diff --git a/paludis/resolver/strongly_connected_component.cc b/paludis/resolver/strongly_connected_component.cc
new file mode 100644
index 0000000..140404d
--- /dev/null
+++ b/paludis/resolver/strongly_connected_component.cc
@@ -0,0 +1,36 @@
+/* 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 <paludis/resolver/strongly_connected_component.hh>
+#include <paludis/resolver/resolvent.hh>
+#include <paludis/util/set-impl.hh>
+#include <paludis/util/sequence-impl.hh>
+#include <paludis/util/wrapped_forward_iterator-impl.hh>
+#include <paludis/util/wrapped_output_iterator-impl.hh>
+
+using namespace paludis;
+using namespace paludis::resolver;
+
+template class Set<Resolvent>;
+template class WrappedForwardIterator<Set<Resolvent>::ConstIteratorTag, const Resolvent>;
+template class WrappedOutputIterator<Set<Resolvent>::InserterTag, Resolvent>;
+
+template class Sequence<StronglyConnectedComponent>;
+template class WrappedForwardIterator<Sequence<StronglyConnectedComponent>::ConstIteratorTag, const StronglyConnectedComponent>;
+
diff --git a/paludis/resolver/strongly_connected_component.hh b/paludis/resolver/strongly_connected_component.hh
new file mode 100644
index 0000000..1c76dcf
--- /dev/null
+++ b/paludis/resolver/strongly_connected_component.hh
@@ -0,0 +1,59 @@
+/* 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_PALUDIS_RESOLVER_STRONGLY_CONNECTED_COMPONENT_HH
+#define PALUDIS_GUARD_PALUDIS_RESOLVER_STRONGLY_CONNECTED_COMPONENT_HH 1
+
+#include <paludis/resolver/strongly_connected_component-fwd.hh>
+#include <paludis/resolver/resolvent-fwd.hh>
+#include <paludis/util/named_value.hh>
+#include <paludis/util/set.hh>
+#include <paludis/util/sequence.hh>
+#include <paludis/util/wrapped_forward_iterator.hh>
+#include <paludis/util/wrapped_output_iterator.hh>
+#include <tr1/memory>
+
+namespace paludis
+{
+ namespace n
+ {
+ typedef Name<struct nodes_name> nodes;
+ typedef Name<struct requirements_name> requirements;
+ }
+
+ namespace resolver
+ {
+ struct StronglyConnectedComponent
+ {
+ NamedValue<n::nodes, std::tr1::shared_ptr<Set<Resolvent> > > nodes;
+ NamedValue<n::requirements, std::tr1::shared_ptr<Set<Resolvent> > > requirements;
+ };
+ }
+
+#ifdef PALUDIS_HAVE_EXTERN_TEMPLATE
+ extern template class Set<resolver::Resolvent>;
+ extern template class WrappedForwardIterator<Set<resolver::Resolvent>::ConstIteratorTag, const resolver::Resolvent>;
+ extern template class WrappedOutputIterator<Set<resolver::Resolvent>::InserterTag, resolver::Resolvent>;
+
+ extern template class Sequence<resolver::StronglyConnectedComponent>;
+ extern template class WrappedForwardIterator<Sequence<resolver::StronglyConnectedComponent>::ConstIteratorTag, const resolver::StronglyConnectedComponent>;
+#endif
+}
+
+#endif
diff --git a/src/clients/cave/Makefile.am b/src/clients/cave/Makefile.am
index c38aa65..cf66170 100644
--- a/src/clients/cave/Makefile.am
+++ b/src/clients/cave/Makefile.am
@@ -144,11 +144,13 @@ libcave_a_SOURCES = \
# cmd_uninstall.cc \
# cmd_uninstall_unused.cc
-TESTS =
+TESTS = \
+ continue_on_failure_TEST
EXTRA_DIST = \
$(man_MANS) \
- $(TESTS)
+ $(TESTS) \
+ continue_on_failure_TEST_setup.sh continue_on_failure_TEST_cleanup.sh
DISTCLEANFILES = $(man_MANS) $(noinst_DATA)
diff --git a/src/clients/cave/cmd_display_resolution.cc b/src/clients/cave/cmd_display_resolution.cc
index 693d0ed..07a24f5 100644
--- a/src/clients/cave/cmd_display_resolution.cc
+++ b/src/clients/cave/cmd_display_resolution.cc
@@ -40,7 +40,7 @@
#include <paludis/util/simple_visitor_cast.hh>
#include <paludis/util/log.hh>
#include <paludis/util/pretty_print.hh>
-#include <paludis/resolver/resolutions.hh>
+#include <paludis/resolver/resolutions_by_resolvent.hh>
#include <paludis/resolver/reason.hh>
#include <paludis/resolver/sanitised_dependencies.hh>
#include <paludis/resolver/resolution.hh>
@@ -50,11 +50,9 @@
#include <paludis/resolver/resolvent.hh>
#include <paludis/resolver/destination.hh>
#include <paludis/resolver/unsuitable_candidates.hh>
-#include <paludis/resolver/resolver_lists.hh>
-#include <paludis/resolver/job.hh>
-#include <paludis/resolver/jobs.hh>
-#include <paludis/resolver/job_id.hh>
+#include <paludis/resolver/decisions.hh>
#include <paludis/resolver/required_confirmations.hh>
+#include <paludis/resolver/orderer_notes.hh>
#include <paludis/package_id.hh>
#include <paludis/version_spec.hh>
#include <paludis/metadata_key.hh>
@@ -398,7 +396,7 @@ namespace
void display_explanations(
const std::tr1::shared_ptr<Environment> & env,
- const ResolverLists & lists,
+ const std::tr1::shared_ptr<const Resolved> & resolved,
const DisplayResolutionCommandLine & cmdline)
{
Context context("When displaying explanations:");
@@ -414,7 +412,8 @@ namespace
{
bool any(false);
PackageDepSpec spec(parse_user_package_dep_spec(*i, env.get(), UserPackageDepSpecOptions() + updso_allow_wildcards));
- for (Resolutions::ConstIterator r(lists.all_resolutions()->begin()), r_end(lists.all_resolutions()->end()) ;
+ for (ResolutionsByResolvent::ConstIterator r(resolved->resolutions_by_resolvent()->begin()),
+ r_end(resolved->resolutions_by_resolvent()->end()) ;
r != r_end ; ++r)
{
if (! decision_matches_spec(env, (*r)->resolvent(), *(*r)->decision(), spec))
@@ -654,10 +653,10 @@ namespace
}
void display_confirmations(
- const Job & job)
+ const ChangesToMakeDecision & decision)
{
- const std::tr1::shared_ptr<const RequiredConfirmations> r(job.required_confirmations());
- if (! r->empty())
+ const std::tr1::shared_ptr<const RequiredConfirmations> r(decision.required_confirmations_if_any());
+ if (r && ! r->empty())
cout << c::bold_red() << " Cannot proceed without: " << c::normal() <<
join(indirect_iterator(r->begin()), indirect_iterator(r->end()), ", ", stringify_confirmation) << endl;
}
@@ -667,10 +666,10 @@ namespace
const DisplayResolutionCommandLine & cmdline,
const ChangesToMakeDecision & decision,
const std::tr1::shared_ptr<const Resolution> & resolution,
- const SimpleInstallJob & job,
const bool more_annotations,
const bool confirmations,
const bool untaken,
+ const std::string & notes,
ChoicesToExplain & choices_to_explain)
{
std::string x("X");
@@ -744,38 +743,27 @@ namespace
display_choices(env, cmdline, decision.origin_id(), old_id, choices_to_explain);
display_reasons(resolution, more_annotations);
if (confirmations)
- display_confirmations(job);
- }
-
- void display_one_install(
- const std::tr1::shared_ptr<Environment> & env,
- const DisplayResolutionCommandLine & cmdline,
- const SimpleInstallJob & job,
- const bool more_annotations,
- const bool confirmations,
- const bool untaken,
- ChoicesToExplain & choices_to_explain)
- {
- display_one_installish(env, cmdline, *job.changes_to_make_decision(), job.resolution(),
- job, more_annotations, confirmations, untaken, choices_to_explain);
+ display_confirmations(decision);
+ if (! notes.empty())
+ cout << " " << c::bold_normal() << notes << c::normal() << endl;
}
void display_one_uninstall(
const std::tr1::shared_ptr<Environment> &,
const DisplayResolutionCommandLine &,
- const UninstallJob & job,
+ const std::tr1::shared_ptr<const Resolution> & resolution,
+ const RemoveDecision & decision,
const bool more_annotations,
- const bool confirmations,
const bool untaken)
{
if (untaken)
- cout << "(<) " << c::bold_green() << job.resolution()->resolvent().package() << c::normal() << " ";
+ cout << "(<) " << c::bold_green() << decision.resolvent().package() << c::normal() << " ";
else
- cout << "< " << c::bold_green() << job.resolution()->resolvent().package() << c::normal() << " ";
+ cout << "< " << c::bold_green() << decision.resolvent().package() << c::normal() << " ";
bool first(true);
- for (PackageIDSequence::ConstIterator i(job.remove_decision()->ids()->begin()),
- i_end(job.remove_decision()->ids()->end()) ;
+ for (PackageIDSequence::ConstIterator i(decision.ids()->begin()),
+ i_end(decision.ids()->end()) ;
i != i_end ; ++i)
{
if (! first)
@@ -786,18 +774,7 @@ namespace
}
cout << endl;
- display_reasons(job.resolution(), more_annotations);
- if (confirmations)
- display_confirmations(job);
- }
-
- void display_special_job_decision(
- const std::tr1::shared_ptr<Environment> &,
- const DisplayResolutionCommandLine &,
- const std::string & job_name,
- const std::tr1::shared_ptr<const PackageID> & id)
- {
- cout << "- " << job_name << " " << *id << endl;
+ display_reasons(resolution, more_annotations);
}
struct NotFixableMask
@@ -1066,151 +1043,122 @@ namespace
}
}
- struct ShowJobsDisplayer
+ void display_choices_to_explain(
+ const std::tr1::shared_ptr<Environment> &,
+ const DisplayResolutionCommandLine &,
+ const ChoicesToExplain & choices_to_explain)
{
- const std::tr1::shared_ptr<Environment> env;
- const DisplayResolutionCommandLine & cmdline;
- const ResolverLists & lists;
- const bool all;
- const bool more_annotations;
- const bool confirmations;
- const bool untaken;
- ChoicesToExplain & choices_to_explain;
-
- ShowJobsDisplayer(
- const std::tr1::shared_ptr<Environment> & e,
- const DisplayResolutionCommandLine & c,
- const ResolverLists & l,
- const bool a,
- const bool n,
- const bool f,
- const bool u,
- ChoicesToExplain & x
- ) :
- env(e),
- cmdline(c),
- lists(l),
- all(a),
- more_annotations(n),
- confirmations(f),
- untaken(u),
- choices_to_explain(x)
- {
- }
-
- bool visit(const SimpleInstallJob & job)
- {
- display_one_install(env, cmdline, job, more_annotations, confirmations, untaken, choices_to_explain);
- return true;
- }
-
- bool visit(const UninstallJob & job)
- {
- display_one_uninstall(env, cmdline, job, more_annotations, confirmations, untaken);
- return true;
- }
-
- bool visit(const UsableJob & job, const bool indent = false)
- {
- if (! all)
- return false;
-
- if (indent)
- cout << " ";
- cout << "- " << c::bold_normal() << job.resolution()->resolvent() << c::normal() << " now usable" << endl;
- return true;
- }
-
- bool visit(const UsableGroupJob & job)
- {
- if (! all)
- return false;
-
- cout << "- " << c::bold_normal() << "group of jobs now usable:" << c::normal() << endl;
- for (JobIDSequence::ConstIterator i(job.job_ids()->begin()), i_end(job.job_ids()->end()) ;
- i != i_end ; ++i)
- visit(*lists.jobs()->fetch_as<UsableJob>(*i), true);
- return true;
- }
+ Context context("When displaying choices to explain:");
- bool visit(const FetchJob & job)
+ for (ChoicesToExplain::const_iterator p(choices_to_explain.begin()), p_end(choices_to_explain.end()) ;
+ p != p_end ; ++p)
{
- if (! all)
- return false;
+ cout << p->first << ":" << endl;
+ for (ChoiceValuesToExplain::const_iterator v(p->second.begin()), v_end(p->second.end()) ;
+ v != v_end ; ++v)
+ {
+ bool all_same(true);
+ const std::tr1::shared_ptr<const ChoiceValue> first_choice_value(
+ (*v->second->begin())->choices_key()->value()->find_by_name_with_prefix(v->first));
+ std::string description(first_choice_value->description());
+ for (PackageIDSequence::ConstIterator w(next(v->second->begin())), w_end(v->second->end()) ;
+ w != w_end ; ++w)
+ if ((*w)->choices_key()->value()->find_by_name_with_prefix(v->first)->description() != description)
+ {
+ all_same = false;
+ break;
+ }
- cout << "- " << c::bold_normal() << job.resolution()->resolvent() << c::normal() << " fetch" << endl;
- return true;
- }
+ if (all_same)
+ cout << " " << std::left << std::setw(30) << (stringify(first_choice_value->unprefixed_name())
+ + ":") << " " << description << endl;
+ else
+ {
+ cout << " " << first_choice_value->unprefixed_name() << ":" << endl;
+ for (PackageIDSequence::ConstIterator w(v->second->begin()), w_end(v->second->end()) ;
+ w != w_end ; ++w)
+ {
+ const std::tr1::shared_ptr<const ChoiceValue> value(
+ (*w)->choices_key()->value()->find_by_name_with_prefix(v->first));
+ cout << " " << std::left << std::setw(30) <<
+ ((*w)->canonical_form(idcf_no_version) + ":") << " " << value->description() << endl;
+ }
+ }
+ }
- bool visit(const ErrorJob &)
- {
- return false;
+ cout << endl;
}
- };
+ }
- struct JobNameVisitor
+ std::pair<std::tr1::shared_ptr<const ChangeOrRemoveDecision>, std::tr1::shared_ptr<const OrdererNotes> >
+ get_decision_and_notes(const std::tr1::shared_ptr<const ChangeOrRemoveDecision> & d)
{
- const std::string visit(const SimpleInstallJob & j) const
- {
- return "install " + stringify(*j.changes_to_make_decision()->origin_id());
- }
-
- const std::string visit(const UninstallJob & j) const
- {
- return "uninstall " + stringify(j.resolution()->resolvent());
- }
-
- const std::string visit(const UsableJob & j) const
- {
- return "usable " + stringify(j.resolution()->resolvent());
- }
-
- const std::string visit(const ErrorJob &) const
- {
- return "error";
- }
-
- const std::string visit(const FetchJob & j) const
- {
- return "fetch " + stringify(*j.changes_to_make_decision()->origin_id());
- }
+ return std::make_pair(d, make_null_shared_ptr());
+ }
- const std::string visit(const UsableGroupJob & j) const
- {
- return "usable (" + stringify(std::distance(j.job_ids()->begin(), j.job_ids()->end())) + ")";
- }
- };
+ std::pair<std::tr1::shared_ptr<const ChangeOrRemoveDecision>, std::tr1::shared_ptr<const OrdererNotes> >
+ get_decision_and_notes(const std::pair<std::tr1::shared_ptr<const ChangeOrRemoveDecision>, std::tr1::shared_ptr<const OrdererNotes> > & d)
+ {
+ return d;
+ }
- void display_jobs(
+ template <typename Decisions_>
+ void display_a_changes_and_removes(
const std::tr1::shared_ptr<Environment> & env,
- const ResolverLists & lists,
+ const std::tr1::shared_ptr<const Resolved> & resolved,
+ const std::tr1::shared_ptr<Decisions_> & decisions,
const DisplayResolutionCommandLine & cmdline,
- ChoicesToExplain & choices_to_explain)
+ ChoicesToExplain & choices_to_explain,
+ const bool more_annotations,
+ const bool unconfirmed,
+ const bool untaken)
{
- Context context("When displaying jobs:");
+ Context context("When displaying changes and removes:");
- cout << "These are the actions I will take, in order:" << endl << endl;
+ if (untaken)
+ cout << "I did not take the following:" << endl << endl;
+ else if (unconfirmed)
+ cout << "I cannot proceed without being permitted to do the following:" << endl << endl;
+ else
+ cout << "These are the actions I will take, in order:" << endl << endl;
bool any(false);
- for (JobIDSequence::ConstIterator i(lists.taken_job_ids()->begin()),
- i_end(lists.taken_job_ids()->end()) ;
+ for (typename Decisions_::ConstIterator i(decisions->begin()), i_end(decisions->end()) ;
i != i_end ; ++i)
{
- const std::tr1::shared_ptr<const Job> job(lists.jobs()->fetch(*i));
- ShowJobsDisplayer d(env, cmdline, lists, cmdline.display_options.a_show_all_jobs.specified() ||
- ! job->used_existing_packages_when_ordering()->empty(), false, false, false, choices_to_explain);
- any |= job->accept_returning<bool>(d);
+ any = true;
+
+ const std::pair<
+ std::tr1::shared_ptr<const ChangeOrRemoveDecision>,
+ std::tr1::shared_ptr<const OrdererNotes> > star_i(get_decision_and_notes(*i));
- if (! job->used_existing_packages_when_ordering()->empty())
+ const ChangesToMakeDecision * const changes_to_make_decision(simple_visitor_cast<const ChangesToMakeDecision>(*star_i.first));
+ const RemoveDecision * const remove_decision(simple_visitor_cast<const RemoveDecision>(*star_i.first));
+ if (changes_to_make_decision)
{
- std::set<std::string> missing;
- for (JobIDSequence::ConstIterator j(job->used_existing_packages_when_ordering()->begin()),
- j_end(job->used_existing_packages_when_ordering()->end()) ;
- j != j_end ; ++j)
- missing.insert(lists.jobs()->fetch(*j)->accept_returning<std::string>(JobNameVisitor()));
- cout << " " << c::bold_normal() << "Couldn't do before: " << c::normal()
- << join(missing.begin(), missing.end(), ", ") << endl;
+ display_one_installish(
+ env,
+ cmdline,
+ *changes_to_make_decision,
+ *resolved->resolutions_by_resolvent()->find(changes_to_make_decision->resolvent()),
+ more_annotations,
+ unconfirmed,
+ untaken,
+ star_i.second ? star_i.second->cycle_breaking() : "",
+ choices_to_explain);
}
+ else if (remove_decision)
+ {
+ display_one_uninstall(
+ env,
+ cmdline,
+ *resolved->resolutions_by_resolvent()->find(remove_decision->resolvent()),
+ *remove_decision,
+ more_annotations,
+ untaken);
+ }
+ else
+ throw InternalError(PALUDIS_HERE, "huh?");
}
if (! any)
@@ -1219,150 +1167,86 @@ namespace
cout << endl;
}
- void display_one_error(
+ void display_changes_and_removes(
const std::tr1::shared_ptr<Environment> & env,
- const DisplayResolutionCommandLine &,
- const std::tr1::shared_ptr<const Resolution> & resolution,
- const ErrorJob & j,
- const bool untaken)
+ const std::tr1::shared_ptr<const Resolved> & resolved,
+ const DisplayResolutionCommandLine & cmdline,
+ ChoicesToExplain & choices_to_explain)
{
- display_unable_to_make_decision(env, resolution, *j.unable_to_make_decision(), untaken);
+ display_a_changes_and_removes(env, resolved, resolved->taken_change_or_remove_decisions(),
+ cmdline, choices_to_explain, false, false, false);
}
- void display_untaken(
+ void display_untaken_changes_and_removes(
const std::tr1::shared_ptr<Environment> & env,
- const ResolverLists & lists,
+ const std::tr1::shared_ptr<const Resolved> & resolved,
const DisplayResolutionCommandLine & cmdline,
ChoicesToExplain & choices_to_explain)
{
- Context context("When displaying untaken jobs:");
+ if (! resolved->untaken_change_or_remove_decisions()->empty())
+ display_a_changes_and_removes(env, resolved, resolved->untaken_change_or_remove_decisions(),
+ cmdline, choices_to_explain, true, false, true);
+ }
- if (lists.untaken_job_ids()->empty() && lists.untaken_error_job_ids()->empty())
- return;
+ void display_an_errors(
+ const std::tr1::shared_ptr<Environment> & env,
+ const std::tr1::shared_ptr<const Resolved> & resolved,
+ const std::tr1::shared_ptr<const Decisions<UnableToMakeDecision> > & decisions,
+ const DisplayResolutionCommandLine &,
+ const bool untaken)
+ {
+ Context context("When displaying errors:");
- cout << "I did not take the following:" << endl << endl;
+ if (untaken)
+ cout << "I encountered the following errors for untaken packages:" << endl << endl;
+ else
+ cout << "I encountered the following errors:" << endl << endl;
- for (JobIDSequence::ConstIterator i(lists.untaken_job_ids()->begin()),
- i_end(lists.untaken_job_ids()->end()) ;
+ bool any(false);
+ for (Decisions<UnableToMakeDecision>::ConstIterator i(decisions->begin()),
+ i_end(decisions->end()) ;
i != i_end ; ++i)
{
- const std::tr1::shared_ptr<const Job> job(lists.jobs()->fetch(*i));
- ShowJobsDisplayer d(env, cmdline, lists, cmdline.display_options.a_show_all_jobs.specified() ||
- ! job->used_existing_packages_when_ordering()->empty(), true, false, true, choices_to_explain);
- if (! job->accept_returning<bool>(d))
- throw InternalError(PALUDIS_HERE, "why didn't we get true?");
- }
+ any = true;
- for (JobIDSequence::ConstIterator i(lists.untaken_error_job_ids()->begin()),
- i_end(lists.untaken_error_job_ids()->end()) ;
- i != i_end ; ++i)
- {
- const std::tr1::shared_ptr<const ErrorJob> job(lists.jobs()->fetch_as<ErrorJob>(*i));
- display_one_error(env, cmdline, job->resolution(), *job, true);
+ display_unable_to_make_decision(
+ env,
+ *resolved->resolutions_by_resolvent()->find((*i)->resolvent()),
+ **i,
+ untaken);
}
cout << endl;
}
- void display_confirmation_jobs(
+ void display_taken_errors(
const std::tr1::shared_ptr<Environment> & env,
- const ResolverLists & lists,
+ const std::tr1::shared_ptr<const Resolved> & resolved,
const DisplayResolutionCommandLine & cmdline)
{
- Context context("When displaying jobs requiring confirmation:");
-
- if (lists.job_ids_needing_confirmation()->empty())
- return;
-
- cout << "I cannot proceed without being permitted to do the following:" << endl << endl;
-
- for (JobIDSequence::ConstIterator i(lists.job_ids_needing_confirmation()->begin()),
- i_end(lists.job_ids_needing_confirmation()->end()) ;
- i != i_end ; ++i)
- {
- const std::tr1::shared_ptr<const Job> job(lists.jobs()->fetch(*i));
- ChoicesToExplain ignore_choices_to_explain;
- ShowJobsDisplayer d(env, cmdline, lists, cmdline.display_options.a_show_all_jobs.specified() ||
- ! job->used_existing_packages_when_ordering()->empty(), true, true, false,
- ignore_choices_to_explain);
- if (! job->accept_returning<bool>(d))
- throw InternalError(PALUDIS_HERE, "why didn't we get true?");
- }
-
- cout << endl;
+ if (! resolved->taken_unable_to_make_decisions()->empty())
+ display_an_errors(env, resolved, resolved->taken_unable_to_make_decisions(), cmdline, false);
}
- void display_errors(
+ void display_untaken_errors(
const std::tr1::shared_ptr<Environment> & env,
- const ResolverLists & lists,
+ const std::tr1::shared_ptr<const Resolved> & resolved,
const DisplayResolutionCommandLine & cmdline)
{
- Context context("When displaying errors:");
-
- if (lists.taken_error_job_ids()->empty())
- return;
-
- cout << "I encountered the following errors:" << endl << endl;
-
- for (JobIDSequence::ConstIterator i(lists.taken_error_job_ids()->begin()),
- i_end(lists.taken_error_job_ids()->end()) ;
- i != i_end ; ++i)
- {
- const std::tr1::shared_ptr<const ErrorJob> job(lists.jobs()->fetch_as<ErrorJob>(*i));
- display_one_error(env, cmdline, job->resolution(), *job, false);
- }
-
- cout << endl;
+ if (! resolved->untaken_unable_to_make_decisions()->empty())
+ display_an_errors(env, resolved, resolved->untaken_unable_to_make_decisions(), cmdline, true);
}
- void display_choices_to_explain(
- const std::tr1::shared_ptr<Environment> &,
- const ResolverLists &,
- const DisplayResolutionCommandLine &,
- const ChoicesToExplain & choices_to_explain)
+ void display_taken_changes_requiring_confirmation(
+ const std::tr1::shared_ptr<Environment> & env,
+ const std::tr1::shared_ptr<const Resolved> & resolved,
+ const DisplayResolutionCommandLine & cmdline)
{
- Context context("When displaying choices to explain:");
-
- for (ChoicesToExplain::const_iterator p(choices_to_explain.begin()), p_end(choices_to_explain.end()) ;
- p != p_end ; ++p)
- {
- cout << p->first << ":" << endl;
- for (ChoiceValuesToExplain::const_iterator v(p->second.begin()), v_end(p->second.end()) ;
- v != v_end ; ++v)
- {
- bool all_same(true);
- const std::tr1::shared_ptr<const ChoiceValue> first_choice_value(
- (*v->second->begin())->choices_key()->value()->find_by_name_with_prefix(v->first));
- std::string description(first_choice_value->description());
- for (PackageIDSequence::ConstIterator w(next(v->second->begin())), w_end(v->second->end()) ;
- w != w_end ; ++w)
- if ((*w)->choices_key()->value()->find_by_name_with_prefix(v->first)->description() != description)
- {
- all_same = false;
- break;
- }
-
- if (all_same)
- cout << " " << std::left << std::setw(30) << (stringify(first_choice_value->unprefixed_name())
- + ":") << " " << description << endl;
- else
- {
- cout << " " << first_choice_value->unprefixed_name() << ":" << endl;
- for (PackageIDSequence::ConstIterator w(v->second->begin()), w_end(v->second->end()) ;
- w != w_end ; ++w)
- {
- const std::tr1::shared_ptr<const ChoiceValue> value(
- (*w)->choices_key()->value()->find_by_name_with_prefix(v->first));
- cout << " " << std::left << std::setw(30) <<
- ((*w)->canonical_form(idcf_no_version) + ":") << " " << value->description() << endl;
- }
- }
- }
-
- cout << endl;
- }
+ ChoicesToExplain ignore_choices_to_explain;
+ if (! resolved->taken_unconfirmed_change_or_remove_decisions()->empty())
+ display_a_changes_and_removes(env, resolved, resolved->taken_unconfirmed_change_or_remove_decisions(),
+ cmdline, ignore_choices_to_explain, true, true, false);
}
-
}
bool
@@ -1375,7 +1259,7 @@ int
DisplayResolutionCommand::run(
const std::tr1::shared_ptr<Environment> & env,
const std::tr1::shared_ptr<const Sequence<std::string > > & args,
- const std::tr1::shared_ptr<const ResolverLists> & maybe_lists
+ const std::tr1::shared_ptr<const Resolved> & maybe_resolved
)
{
DisplayResolutionCommandLine cmdline;
@@ -1389,8 +1273,8 @@ DisplayResolutionCommand::run(
cmdline.import_options.apply(env);
- std::tr1::shared_ptr<const ResolverLists> lists(maybe_lists);
- if (! lists)
+ std::tr1::shared_ptr<const Resolved> resolved(maybe_resolved);
+ if (! resolved)
{
if (getenv_with_default("PALUDIS_SERIALISED_RESOLUTION_FD", "").empty())
throw args::DoHelp("PALUDIS_SERIALISED_RESOLUTION_FD must be provided");
@@ -1398,18 +1282,19 @@ DisplayResolutionCommand::run(
int fd(destringify<int>(getenv_with_default("PALUDIS_SERIALISED_RESOLUTION_FD", "")));
SafeIFStream deser_stream(fd);
Deserialiser deserialiser(env.get(), deser_stream);
- Deserialisation deserialisation("ResolverLists", deserialiser);
- lists = make_shared_copy(ResolverLists::deserialise(deserialisation));
+ Deserialisation deserialisation("Resolved", deserialiser);
+ resolved = make_shared_copy(Resolved::deserialise(deserialisation));
close(fd);
}
ChoicesToExplain choices_to_explain;
- display_jobs(env, *lists, cmdline, choices_to_explain);
- display_untaken(env, *lists, cmdline, choices_to_explain);
- display_choices_to_explain(env, *lists, cmdline, choices_to_explain);
- display_confirmation_jobs(env, *lists, cmdline);
- display_errors(env, *lists, cmdline);
- display_explanations(env, *lists, cmdline);
+ display_changes_and_removes(env, resolved, cmdline, choices_to_explain);
+ display_untaken_changes_and_removes(env, resolved, cmdline, choices_to_explain);
+ display_choices_to_explain(env, cmdline, choices_to_explain);
+ display_taken_errors(env, resolved, cmdline);
+ display_untaken_errors(env, resolved, cmdline);
+ display_taken_changes_requiring_confirmation(env, resolved, cmdline);
+ display_explanations(env, resolved, cmdline);
return 0;
}
diff --git a/src/clients/cave/cmd_display_resolution.hh b/src/clients/cave/cmd_display_resolution.hh
index 6f01f7f..aa23e8a 100644
--- a/src/clients/cave/cmd_display_resolution.hh
+++ b/src/clients/cave/cmd_display_resolution.hh
@@ -21,7 +21,7 @@
#define PALUDIS_GUARD_SRC_CLIENTS_CAVE_CMD_DISPLAY_RESOLUTION_HH 1
#include "command.hh"
-#include <paludis/resolver/resolver_lists-fwd.hh>
+#include <paludis/resolver/resolved-fwd.hh>
namespace paludis
{
@@ -41,7 +41,7 @@ namespace paludis
int run(
const std::tr1::shared_ptr<Environment> &,
const std::tr1::shared_ptr<const Sequence<std::string > > & args,
- const std::tr1::shared_ptr<const resolver::ResolverLists> & maybe_lists
+ const std::tr1::shared_ptr<const resolver::Resolved> & maybe_resolved
);
std::tr1::shared_ptr<args::ArgsHandler> make_doc_cmdline();
diff --git a/src/clients/cave/cmd_execute_resolution.cc b/src/clients/cave/cmd_execute_resolution.cc
index 26a689f..eebf62d 100644
--- a/src/clients/cave/cmd_execute_resolution.cc
+++ b/src/clients/cave/cmd_execute_resolution.cc
@@ -40,7 +40,8 @@
#include <paludis/util/make_shared_copy.hh>
#include <paludis/util/hashes.hh>
#include <paludis/util/type_list.hh>
-#include <paludis/resolver/resolutions.hh>
+#include <paludis/util/indirect_iterator-impl.hh>
+#include <paludis/resolver/resolutions_by_resolvent.hh>
#include <paludis/resolver/reason.hh>
#include <paludis/resolver/sanitised_dependencies.hh>
#include <paludis/resolver/resolution.hh>
@@ -49,12 +50,11 @@
#include <paludis/resolver/resolver.hh>
#include <paludis/resolver/resolvent.hh>
#include <paludis/resolver/destination.hh>
-#include <paludis/resolver/resolver_lists.hh>
-#include <paludis/resolver/jobs.hh>
+#include <paludis/resolver/job_lists.hh>
+#include <paludis/resolver/job_list.hh>
#include <paludis/resolver/job.hh>
-#include <paludis/resolver/job_id.hh>
#include <paludis/resolver/job_state.hh>
-#include <paludis/resolver/arrow.hh>
+#include <paludis/resolver/job_requirements.hh>
#include <paludis/package_id.hh>
#include <paludis/version_spec.hh>
#include <paludis/metadata_key.hh>
@@ -128,15 +128,15 @@ namespace
bool do_pretend(
const std::tr1::shared_ptr<Environment> & env,
const ExecuteResolutionCommandLine & cmdline,
- const ChangesToMakeDecision & decision,
+ const std::tr1::shared_ptr<const PackageID> & origin_id,
const int x, const int y, const int last_x,
std::tr1::shared_ptr<OutputManager> & output_manager_goes_here)
{
- Context context("When pretending for '" + stringify(*decision.origin_id()) + "':");
+ Context context("When pretending for '" + stringify(*origin_id) + "':");
if (0 != last_x)
- std::cout << std::string(stringify(last_x).length() + stringify(y).length() + 4, '\010');
- std::cout << x << " of " << y << std::flush;
+ cout << std::string(stringify(last_x).length() + stringify(y).length() + 4, '\010');
+ cout << x << " of " << y << std::flush;
std::tr1::shared_ptr<Sequence<std::string> > args(new Sequence<std::string>);
@@ -145,7 +145,7 @@ namespace
args->push_back("--if-supported");
args->push_back("--x-of-y");
args->push_back(stringify(x) + " of " + stringify(y));
- args->push_back(stringify(decision.origin_id()->uniquely_identifying_spec()));
+ args->push_back(stringify(origin_id->uniquely_identifying_spec()));
int retcode;
@@ -222,15 +222,13 @@ namespace
bool do_fetch(
const std::tr1::shared_ptr<Environment> & env,
const ExecuteResolutionCommandLine & cmdline,
- const ChangesToMakeDecision & decision,
+ const std::tr1::shared_ptr<const PackageID> & id,
const int x, const int y, bool normal_only,
- std::tr1::shared_ptr<OutputManager> & output_manager_goes_here)
+ JobActiveState & active_state)
{
- const std::tr1::shared_ptr<const PackageID> id(decision.origin_id());
Context context("When fetching for '" + stringify(*id) + "':");
- starting_action("fetch (" + std::string(normal_only ? "regular parts" : "extra parts") + ")",
- decision.origin_id(), x, y);
+ starting_action("fetch (" + std::string(normal_only ? "regular parts" : "extra parts") + ")", id, x, y);
std::string command(cmdline.program_options.a_perform_program.argument());
if (command.empty())
@@ -290,24 +288,25 @@ namespace
if (output_manager)
{
output_manager->nothing_more_to_come();
- output_manager_goes_here = output_manager;
+ active_state.set_output_manager(output_manager);
}
- done_action("fetch (" + std::string(normal_only ? "regular parts" : "extra parts") + ")",
- decision.origin_id(), 0 == retcode);
+ done_action("fetch (" + std::string(normal_only ? "regular parts" : "extra parts") + ")", id, 0 == retcode);
return 0 == retcode;
}
bool do_install(
const std::tr1::shared_ptr<Environment> & env,
const ExecuteResolutionCommandLine & cmdline,
- const std::tr1::shared_ptr<const Resolution> & resolution,
- const ChangesToMakeDecision & decision,
+ const std::tr1::shared_ptr<const PackageID> & id,
+ const RepositoryName & destination_repository_name,
+ const std::tr1::shared_ptr<const PackageIDSequence> & replacing,
+ const DestinationType & destination_type,
const int x, const int y,
- std::tr1::shared_ptr<OutputManager> & output_manager_goes_here)
+ JobActiveState & active_state)
{
std::string destination_string, action_string;
- switch (resolution->resolvent().destination_type())
+ switch (destination_type)
{
case dt_install_to_slash:
destination_string = "installing to /";
@@ -326,10 +325,9 @@ namespace
if (destination_string.empty())
throw InternalError(PALUDIS_HERE, "unhandled dt");
- const std::tr1::shared_ptr<const PackageID> id(decision.origin_id());
Context context("When " + destination_string + " for '" + stringify(*id) + "':");
- starting_action(action_string, decision.origin_id(), x, y);
+ starting_action(action_string, id, x, y);
std::string command(cmdline.program_options.a_perform_program.argument());
if (command.empty())
@@ -337,9 +335,9 @@ namespace
command.append(" install --hooks --managed-output ");
command.append(stringify(id->uniquely_identifying_spec()));
- command.append(" --destination " + stringify(decision.destination()->repository()));
- for (PackageIDSequence::ConstIterator i(decision.destination()->replacing()->begin()),
- i_end(decision.destination()->replacing()->end()) ;
+ command.append(" --destination " + stringify(destination_repository_name));
+ for (PackageIDSequence::ConstIterator i(replacing->begin()),
+ i_end(replacing->end()) ;
i != i_end ; ++i)
command.append(" --replacing " + stringify((*i)->uniquely_identifying_spec()));
@@ -392,20 +390,19 @@ namespace
if (output_manager)
{
output_manager->nothing_more_to_come();
- output_manager_goes_here = output_manager;
+ active_state.set_output_manager(output_manager);
}
- done_action(action_string, decision.origin_id(), 0 == retcode);
+ done_action(action_string, id, 0 == retcode);
return 0 == retcode;
}
bool do_uninstall(
const std::tr1::shared_ptr<Environment> & env,
const ExecuteResolutionCommandLine & cmdline,
- const std::tr1::shared_ptr<const Resolution> &,
const std::tr1::shared_ptr<const PackageID> & id,
const int x, const int y,
- std::tr1::shared_ptr<OutputManager> & output_manager_goes_here)
+ JobActiveState & active_state)
{
Context context("When removing '" + stringify(*id) + "':");
@@ -467,303 +464,14 @@ namespace
if (output_manager)
{
output_manager->nothing_more_to_come();
- output_manager_goes_here = output_manager;
+ output_manager->succeeded();
+ active_state.set_output_manager(output_manager);
}
done_action("remove", id, 0 == retcode);
return 0 == retcode;
}
- struct JobCounts
- {
- int x_fetches, y_fetches, x_installs, y_installs;
-
- JobCounts() :
- x_fetches(0),
- y_fetches(0),
- x_installs(0),
- y_installs(0)
- {
- }
-
- void visit(const SimpleInstallJob &)
- {
- ++y_installs;
- }
-
- void visit(const UninstallJob &)
- {
- /* we'll count uninstalls as installs for now. this might be
- * confusing, or it might make most sense. if you're reading this,
- * chances are you think it's the wrong thing to do. */
- ++y_installs;
- }
-
- void visit(const FetchJob &)
- {
- ++y_fetches;
- }
-
- void visit(const UsableJob &)
- {
- }
-
- void visit(const UsableGroupJob &)
- {
- }
-
- void visit(const ErrorJob &)
- {
- }
- };
-
- typedef std::tr1::unordered_map<JobID, std::tr1::shared_ptr<JobState>, Hash<JobID> > JobStateMap;
- typedef std::list<std::tr1::shared_ptr<JobPendingState> > PendingJobsList;
- typedef std::list<std::tr1::shared_ptr<JobState> > Summary;
-
- struct DoOneTakenVisitor
- {
- const std::tr1::shared_ptr<Environment> env;
- const ExecuteResolutionCommandLine & cmdline;
- JobCounts & counts;
- std::tr1::shared_ptr<JobState> & state;
- JobStateMap & job_state_map;
-
- DoOneTakenVisitor(
- const std::tr1::shared_ptr<Environment> & e,
- const ExecuteResolutionCommandLine & c,
- JobCounts & k,
- std::tr1::shared_ptr<JobState> & s,
- JobStateMap & m) :
- env(e),
- cmdline(c),
- counts(k),
- state(s),
- job_state_map(m)
- {
- }
-
- bool visit(const SimpleInstallJob & job)
- {
- std::tr1::shared_ptr<OutputManager> fetch_output_manager_goes_here, install_output_manager_goes_here;
-
- ++counts.x_installs;
-
- /* not all of the fetch is done in the background */
- if (! do_fetch(env, cmdline, *job.changes_to_make_decision(), counts.x_installs, counts.y_installs,
- false, fetch_output_manager_goes_here))
- {
- std::tr1::shared_ptr<JobFailedState> failed_state(new JobFailedState(state->job()));
- if (fetch_output_manager_goes_here)
- failed_state->add_output_manager(fetch_output_manager_goes_here);
- state = failed_state;
- return false;
- }
-
- if (! do_install(env, cmdline, job.resolution(),
- *job.changes_to_make_decision(), counts.x_installs, counts.y_installs, install_output_manager_goes_here))
- {
- std::tr1::shared_ptr<JobFailedState> failed_state(new JobFailedState(state->job()));
- if (fetch_output_manager_goes_here)
- failed_state->add_output_manager(fetch_output_manager_goes_here);
- if (install_output_manager_goes_here)
- failed_state->add_output_manager(install_output_manager_goes_here);
- state = failed_state;
- return false;
- }
- else
- {
- std::tr1::shared_ptr<JobSucceededState> succeeded_state(new JobSucceededState(state->job()));
- if (fetch_output_manager_goes_here)
- succeeded_state->add_output_manager(fetch_output_manager_goes_here);
- if (install_output_manager_goes_here)
- succeeded_state->add_output_manager(install_output_manager_goes_here);
- state = succeeded_state;
- return true;
- }
- }
-
- bool visit(const UninstallJob & job)
- {
- std::list<std::tr1::shared_ptr<OutputManager> > output_managers;
-
- ++counts.x_installs;
-
- bool failed(false);
- for (PackageIDSequence::ConstIterator i(job.remove_decision()->ids()->begin()),
- i_end(job.remove_decision()->ids()->end()) ;
- i != i_end ; ++i)
- {
- std::tr1::shared_ptr<OutputManager> uninstall_output_manager_goes_here;
- if (! do_uninstall(env, cmdline, job.resolution(),
- *i, counts.x_installs, counts.y_installs, uninstall_output_manager_goes_here))
- failed = true;
- if (uninstall_output_manager_goes_here)
- output_managers.push_back(uninstall_output_manager_goes_here);
- }
-
- if (failed)
- {
- std::tr1::shared_ptr<JobFailedState> failed_state(new JobFailedState(state->job()));
- std::for_each(output_managers.begin(), output_managers.end(),
- std::tr1::bind(&JobFailedState::add_output_manager, failed_state, std::tr1::placeholders::_1));
- state = failed_state;
- return false;
- }
- else
- {
- std::tr1::shared_ptr<JobSucceededState> succeeded_state(new JobSucceededState(state->job()));
-
- /* uninstalls don't mark success themselves, to avoid confusing
- * things when called as part of an install. maybe we should
- * mark success individually rather than all together if we're
- * uninstalling multiple things. */
- std::for_each(output_managers.begin(), output_managers.end(),
- std::tr1::bind(&OutputManager::succeeded, std::tr1::placeholders::_1));
-
- std::for_each(output_managers.begin(), output_managers.end(),
- std::tr1::bind(&JobSucceededState::add_output_manager, succeeded_state, std::tr1::placeholders::_1));
- state = succeeded_state;
- return true;
- }
- }
-
- bool visit(const FetchJob & job)
- {
- std::tr1::shared_ptr<OutputManager> output_manager_goes_here;
-
- ++counts.x_fetches;
- if (! do_fetch(env, cmdline, *job.changes_to_make_decision(), counts.x_fetches, counts.y_fetches,
- true, output_manager_goes_here))
- {
- std::tr1::shared_ptr<JobFailedState> failed_state(new JobFailedState(state->job()));
- if (output_manager_goes_here)
- failed_state->add_output_manager(output_manager_goes_here);
- state = failed_state;
- return false;
- }
- else
- {
- std::tr1::shared_ptr<JobSucceededState> succeeded_state(new JobSucceededState(state->job()));
- if (output_manager_goes_here)
- succeeded_state->add_output_manager(output_manager_goes_here);
- state = succeeded_state;
- return true;
- }
- }
-
- bool visit(const ErrorJob &)
- {
- state.reset(new JobFailedState(state->job()));
- return false;
- }
-
- bool visit(const UsableJob &)
- {
- state.reset(new JobSucceededState(state->job()));
- return true;
- }
-
- bool visit(const UsableGroupJob & job)
- {
- bool result(true);
-
- for (JobIDSequence::ConstIterator i(job.job_ids()->begin()), i_end(job.job_ids()->end()) ;
- i != i_end ; ++i)
- {
- JobStateMap::iterator s(job_state_map.find(*i));
- if (s == job_state_map.end())
- throw InternalError(PALUDIS_HERE, "missing state");
-
- DoOneTakenVisitor v(env, cmdline, counts, s->second, job_state_map);
- result = s->second->job()->accept_returning<bool>(v) && result;
- }
-
- state.reset(new JobSucceededState(state->job()));
- return result;
- }
- };
-
- struct DoOneSkippedVisitor
- {
- const std::tr1::shared_ptr<Environment> env;
- const ExecuteResolutionCommandLine & cmdline;
- JobCounts & counts;
- std::tr1::shared_ptr<JobState> & state;
- JobStateMap & job_state_map;
-
- DoOneSkippedVisitor(
- const std::tr1::shared_ptr<Environment> & e,
- const ExecuteResolutionCommandLine & c,
- JobCounts & k,
- std::tr1::shared_ptr<JobState> & s,
- JobStateMap & m) :
- env(e),
- cmdline(c),
- counts(k),
- state(s),
- job_state_map(m)
- {
- }
-
- void visit(const SimpleInstallJob & job)
- {
- ++counts.x_installs;
-
- cout << endl;
- cout << c::bold_blue() << counts.x_installs << " of " << counts.y_installs << ": Skipping install of "
- << *job.changes_to_make_decision()->origin_id() << c::normal() << endl;
- cout << endl;
-
- state.reset(new JobSkippedState(state->job()));
- }
-
- void visit(const UninstallJob & job)
- {
- ++counts.x_installs;
-
- cout << endl;
- cout << c::bold_blue() << counts.x_installs << " of " << counts.y_installs << ": Skipping uninstall of "
- << job.resolution()->resolvent() << c::normal() << endl;
- cout << endl;
-
- state.reset(new JobSkippedState(state->job()));
- }
-
- void visit(const FetchJob &)
- {
- ++counts.x_fetches;
-
- state.reset(new JobSkippedState(state->job()));
- }
-
- void visit(const ErrorJob &)
- {
- state.reset(new JobSkippedState(state->job()));
- }
-
- void visit(const UsableJob &)
- {
- state.reset(new JobSkippedState(state->job()));
- }
-
- void visit(const UsableGroupJob & job)
- {
- for (JobIDSequence::ConstIterator i(job.job_ids()->begin()), i_end(job.job_ids()->end()) ;
- i != i_end ; ++i)
- {
- JobStateMap::iterator s(job_state_map.find(*i));
- if (s == job_state_map.end())
- throw InternalError(PALUDIS_HERE, "missing state");
-
- DoOneSkippedVisitor v(env, cmdline, counts, s->second, job_state_map);
- s->second->job()->accept(v);
- }
-
- state.reset(new JobSkippedState(state->job()));
- }
- };
-
void update_world(
const std::tr1::shared_ptr<Environment> & env,
const ExecuteResolutionCommandLine & cmdline,
@@ -864,7 +572,6 @@ namespace
void execute_update_world(
const std::tr1::shared_ptr<Environment> & env,
- const ResolverLists &,
const ExecuteResolutionCommandLine & cmdline)
{
if (cmdline.execution_options.a_preserve_world.specified())
@@ -876,184 +583,210 @@ namespace
update_world(env, cmdline, false);
}
- struct Populator
+ int execute_pretends(
+ const std::tr1::shared_ptr<Environment> & env,
+ const std::tr1::shared_ptr<JobLists> & lists,
+ const ExecuteResolutionCommandLine & cmdline)
{
- const std::tr1::shared_ptr<const Job> job;
- const ResolverLists & lists;
- JobStateMap & job_state_map;
- PendingJobsList * const pending;
-
- Populator(
- const std::tr1::shared_ptr<const Job> & j,
- const ResolverLists & l,
- JobStateMap & s,
- PendingJobsList * const p) :
- job(j),
- lists(l),
- job_state_map(s),
- pending(p)
- {
- }
+ bool failed(false);
+ int x(0), y(lists->pretend_job_list()->length()), last_x(0);
+
+ if (0 != env->perform_hook(Hook("pretend_all_pre")
+ ("TARGETS", join(cmdline.begin_parameters(), cmdline.end_parameters(), " "))
+ ).max_exit_status())
+ throw ActionAbortedError("Aborted by hook");
- void common() const
+ for (JobList<PretendJob>::ConstIterator c(lists->pretend_job_list()->begin()),
+ c_end(lists->pretend_job_list()->end()) ;
+ c != c_end ; ++c)
{
- const std::tr1::shared_ptr<JobPendingState> state(new JobPendingState(job));
- if (! job_state_map.insert(std::make_pair(job->id(), state)).second)
- throw InternalError(PALUDIS_HERE, "duplicate id");
+ if (++x == 1)
+ cout << "Executing pretend actions: " << std::flush;
- if (pending)
- pending->push_back(state);
+ std::tr1::shared_ptr<OutputManager> output_manager_goes_here;
+ failed = failed || ! do_pretend(env, cmdline, (*c)->origin_id(), x, y, last_x, output_manager_goes_here);
+ last_x = x;
}
- void visit(const SimpleInstallJob &) const
- {
- common();
- }
+ if (0 != last_x)
+ cout << endl;
- void visit(const UninstallJob &) const
- {
- common();
- }
+ if (0 != env->perform_hook(Hook("pretend_all_post")
+ ("TARGETS", join(cmdline.begin_parameters(), cmdline.end_parameters(), " "))
+ ).max_exit_status())
+ throw ActionAbortedError("Aborted by hook");
- void visit(const UsableJob &) const
+ return failed ? 1 : 0;
+ }
+
+ struct ExecuteOneVisitor
+ {
+ const std::tr1::shared_ptr<Environment> env;
+ const ExecuteResolutionCommandLine & cmdline;
+ int & x;
+ const int y;
+
+ ExecuteOneVisitor(
+ const std::tr1::shared_ptr<Environment> & e,
+ const ExecuteResolutionCommandLine & c,
+ int & xx, int yy) :
+ env(e),
+ cmdline(c),
+ x(xx),
+ y(yy)
{
- common();
}
- void visit(const FetchJob &) const
+ int visit(InstallJob & install_item)
{
- common();
+ ++x;
+
+ const std::tr1::shared_ptr<JobActiveState> active_state(new JobActiveState);
+ install_item.set_state(active_state);
+
+ if (! do_fetch(env, cmdline, install_item.origin_id(), x, y, false, *active_state))
+ {
+ install_item.set_state(active_state->failed());
+ return 1;
+ }
+
+ if (! do_install(env, cmdline, install_item.origin_id(), install_item.destination_repository_name(),
+ install_item.replacing(), install_item.destination_type(),
+ x, y, *active_state))
+ {
+ install_item.set_state(active_state->failed());
+ return 1;
+ }
+
+ install_item.set_state(active_state->succeeded());
+ return 0;
}
- void visit(const ErrorJob &) const
+ int visit(UninstallJob & uninstall_item)
{
- common();
+ ++x;
+
+ const std::tr1::shared_ptr<JobActiveState> active_state(new JobActiveState);
+ uninstall_item.set_state(active_state);
+
+ for (PackageIDSequence::ConstIterator i(uninstall_item.ids_to_remove()->begin()),
+ i_end(uninstall_item.ids_to_remove()->end()) ;
+ i != i_end ; ++i)
+ if (! do_uninstall(env, cmdline, *i, x, y, *active_state))
+ {
+ uninstall_item.set_state(active_state->failed());
+ return 1;
+ }
+
+ uninstall_item.set_state(active_state->succeeded());
+ return 0;
}
- void visit(const UsableGroupJob & j) const
+ int visit(FetchJob & fetch_item)
{
- common();
+ ++x;
- for (JobIDSequence::ConstIterator i(j.job_ids()->begin()), i_end(j.job_ids()->end()) ;
- i != i_end ; ++i)
+ const std::tr1::shared_ptr<JobActiveState> active_state(new JobActiveState);
+ fetch_item.set_state(active_state);
+
+ if (! do_fetch(env, cmdline, fetch_item.origin_id(), x, y, true, *active_state))
{
- const std::tr1::shared_ptr<const Job> k(lists.jobs()->fetch(*i));
- k->accept(Populator(k, lists, job_state_map, 0));
+ fetch_item.set_state(active_state->failed());
+ return 1;
}
+
+ fetch_item.set_state(active_state->succeeded());
+ return 0;
}
};
- struct JobStateChecker
+ struct ContinueAfterState
{
- bool visit(const JobPendingState &) const PALUDIS_ATTRIBUTE((noreturn))
+ bool visit(const JobPendingState &) const
{
- throw InternalError(PALUDIS_HERE, "still pending");
+ /* it's still pending because it's a circular dep that we ended up ignoring */
+ return true;
}
- bool visit(const JobFailedState &) const
+ bool visit(const JobActiveState &) const PALUDIS_ATTRIBUTE((noreturn))
{
- return false;
+ throw InternalError(PALUDIS_HERE, "still active? how did that happen?");
}
- bool visit(const JobSkippedState &) const
+ bool visit(const JobSucceededState &) const
+ {
+ return true;
+ }
+
+ bool visit(const JobFailedState &) const
{
return false;
}
- bool visit(const JobSucceededState &) const
+ bool visit(const JobSkippedState &) const
{
- return true;
+ return false;
}
};
- int execute_taken(
+ int execute_executions(
const std::tr1::shared_ptr<Environment> & env,
- const ResolverLists & lists,
- const ExecuteResolutionCommandLine & cmdline,
- Summary & summary)
+ const std::tr1::shared_ptr<JobLists> & lists,
+ const ExecuteResolutionCommandLine & cmdline)
{
int retcode(0);
-
- JobCounts counts;
- JobStateMap job_state_map;
- PendingJobsList pending;
-
- for (JobIDSequence::ConstIterator c(lists.taken_job_ids()->begin()),
- c_end(lists.taken_job_ids()->end()) ;
- c != c_end ; ++c)
- {
- const std::tr1::shared_ptr<const Job> job(lists.jobs()->fetch(*c));
- job->accept(counts);
- job->accept(Populator(job, lists, job_state_map, &pending));
- }
+ int x(0), y(lists->execute_job_list()->length());
if (0 != env->perform_hook(Hook("install_all_pre")
("TARGETS", join(cmdline.begin_parameters(), cmdline.end_parameters(), " "))
).max_exit_status())
throw ActionAbortedError("Aborted by hook");
- for (PendingJobsList::iterator p(pending.begin()), p_next(p), p_end(pending.end()) ;
- p != p_end ; p = p_next)
+ JobRequirementIf require_if(last_jri);
+ if (cmdline.execution_options.a_continue_on_failure.argument() == "always")
+ require_if = jri_require_always;
+ else if (cmdline.execution_options.a_continue_on_failure.argument() == "if-satisfied")
+ require_if = jri_require_for_satisfied;
+ else if (cmdline.execution_options.a_continue_on_failure.argument() == "if-independent")
+ require_if = jri_require_for_independent;
+ else if (cmdline.execution_options.a_continue_on_failure.argument() == "never")
+ require_if = last_jri;
+ else
+ throw args::DoHelp("Don't understand argument '"
+ + cmdline.execution_options.a_continue_on_failure.argument() + "' to '--"
+ + cmdline.execution_options.a_continue_on_failure.long_name() + "'");
+
+ for (JobList<ExecuteJob>::ConstIterator c(lists->execute_job_list()->begin()),
+ c_end(lists->execute_job_list()->end()) ;
+ c != c_end ; ++c)
{
- ++p_next;
+ bool want(true);
- std::tr1::shared_ptr<const Job> skipped_because_of;
- for (ArrowSequence::ConstIterator a((*p)->job()->arrows()->begin()), a_end((*p)->job()->arrows()->end()) ;
- a != a_end ; ++a)
+ if (0 != retcode)
{
- const std::tr1::shared_ptr<const Job> after_job(lists.jobs()->fetch(a->comes_after()));
- JobStateMap::const_iterator s(job_state_map.find(after_job->id()));
- if (s == job_state_map.end())
- throw InternalError(PALUDIS_HERE, "missing arrow: " + stringify(after_job->id().string_id()));
-
- if ((*p)->job()->used_existing_packages_when_ordering()->end() != std::find(
- (*p)->job()->used_existing_packages_when_ordering()->begin(),
- (*p)->job()->used_existing_packages_when_ordering()->end(),
- a->comes_after()))
- {
- if (! simple_visitor_cast<const JobPendingState>(*s->second))
- throw InternalError(PALUDIS_HERE, "not pending: " + stringify((*p)->job()->id().string_id()) + " -> "
- + stringify(a->comes_after().string_id()) + " " + s->second->state_name());
- }
+ if (last_jri == require_if)
+ want = false;
else
{
- bool ignorable(false);
-
- if (cmdline.execution_options.a_continue_on_failure.argument() == "if-satisfied")
- ignorable = a->failure_kinds()[fk_ignorable_if_satisfied];
- else if (cmdline.execution_options.a_continue_on_failure.argument() == "always")
- ignorable = true;
-
- if ((! ignorable) && (! s->second->accept_returning<bool>(JobStateChecker())))
+ for (JobRequirements::ConstIterator r((*c)->requirements()->begin()), r_end((*c)->requirements()->end()) ;
+ r != r_end && want ; ++r)
{
- skipped_because_of = after_job;
- break;
+ if (! r->required_if()[require_if])
+ continue;
+
+ const std::tr1::shared_ptr<const ExecuteJob> req(*lists->execute_job_list()->fetch(r->job_number()));
+ want = want && req->state()->accept_returning<bool>(ContinueAfterState());
}
}
}
- JobStateMap::iterator s(job_state_map.find((*p)->job()->id()));
- if (s == job_state_map.end())
- throw InternalError(PALUDIS_HERE, "missing state");
- pending.erase(p);
-
- if (skipped_because_of)
+ if (want)
{
- DoOneSkippedVisitor v(env, cmdline, counts, s->second, job_state_map);
- s->second->job()->accept(v);
- retcode |= 1;
+ ExecuteOneVisitor execute(env, cmdline, x, y);
+ retcode |= (*c)->accept_returning<int>(execute);
}
else
- {
- DoOneTakenVisitor v(env, cmdline, counts, s->second, job_state_map);
- if (! s->second->job()->accept_returning<bool>(v))
- retcode |= 1;
- }
-
- summary.push_back(s->second);
-
- if ((0 != retcode) && (cmdline.execution_options.a_continue_on_failure.argument() == "never"))
- break;
+ (*c)->set_state(make_shared_ptr(new JobSkippedState));
}
if (0 != env->perform_hook(Hook("install_all_post")
@@ -1064,254 +797,129 @@ namespace
return retcode;
}
- struct DoOnePretendVisitor
- {
- const std::tr1::shared_ptr<Environment> env;
- const ExecuteResolutionCommandLine & cmdline;
- JobCounts & counts;
- int & last_x;
-
- DoOnePretendVisitor(
- const std::tr1::shared_ptr<Environment> & e,
- const ExecuteResolutionCommandLine & c,
- JobCounts & k,
- int & l) :
- env(e),
- cmdline(c),
- counts(k),
- last_x(l)
- {
- }
-
- bool visit(const SimpleInstallJob & c) const
- {
- if (0 == last_x)
- std::cout << "Executing pretend actions: " << std::flush;
-
- std::tr1::shared_ptr<OutputManager> output_manager_goes_here;
- return do_pretend(env, cmdline, *c.changes_to_make_decision(), ++counts.x_installs, counts.y_installs,
- last_x++, output_manager_goes_here);
- }
-
- bool visit(const UninstallJob &) const
- {
- ++counts.x_installs;
- return true;
- }
-
- bool visit(const ErrorJob &) const
- {
- return true;
- }
-
- bool visit(const FetchJob &) const
- {
- return true;
- }
-
- bool visit(const UsableJob &) const
- {
- return true;
- }
-
- bool visit(const UsableGroupJob &) const
- {
- return true;
- }
- };
-
- int execute_pretends(
+ int execute_resolution_main(
const std::tr1::shared_ptr<Environment> & env,
- const ResolverLists & lists,
+ const std::tr1::shared_ptr<JobLists> & lists,
const ExecuteResolutionCommandLine & cmdline)
{
- bool failed(false);
- JobCounts counts;
- int last_x(0);
-
- for (JobIDSequence::ConstIterator c(lists.taken_job_ids()->begin()),
- c_end(lists.taken_job_ids()->end()) ;
- c != c_end ; ++c)
- lists.jobs()->fetch(*c)->accept(counts);
-
- if (0 != env->perform_hook(Hook("pretend_all_pre")
- ("TARGETS", join(cmdline.begin_parameters(), cmdline.end_parameters(), " "))
- ).max_exit_status())
- throw ActionAbortedError("Aborted by hook");
-
- for (JobIDSequence::ConstIterator c(lists.taken_job_ids()->begin()),
- c_end(lists.taken_job_ids()->end()) ;
+ for (JobList<ExecuteJob>::ConstIterator c(lists->execute_job_list()->begin()),
+ c_end(lists->execute_job_list()->end()) ;
c != c_end ; ++c)
- failed = failed || ! lists.jobs()->fetch(*c)->accept_returning<bool>(DoOnePretendVisitor(
- env, cmdline, counts, last_x));
-
- if (0 != last_x)
- cout << endl;
-
- if (0 != env->perform_hook(Hook("pretend_all_post")
- ("TARGETS", join(cmdline.begin_parameters(), cmdline.end_parameters(), " "))
- ).max_exit_status())
- throw ActionAbortedError("Aborted by hook");
-
- return failed ? 1 : 0;
- }
+ (*c)->set_state(make_shared_ptr(new JobPendingState));
- int execute_resolution_main(
- const std::tr1::shared_ptr<Environment> & env,
- const ResolverLists & lists,
- const ExecuteResolutionCommandLine & cmdline,
- Summary & summary)
- {
int retcode(0);
retcode |= execute_pretends(env, lists, cmdline);
if (0 != retcode || cmdline.a_pretend.specified())
return retcode;
- retcode |= execute_taken(env, lists, cmdline, summary);
+ retcode |= execute_executions(env, lists, cmdline);
if (0 != retcode)
return retcode;
- execute_update_world(env, lists, cmdline);
+ execute_update_world(env, cmdline);
+
return retcode;
}
- struct SummaryJobNameDisplayer
+ struct SummaryNameVisitor
{
- const ResolverLists & lists;
- const std::string colour;
- const std::string state;
- const bool want_to_flush;
- const bool this_failed;
- const bool something_failed;
- bool & done_summary;
-
- SummaryJobNameDisplayer(
- const ResolverLists & l,
- const std::string & c,
- const std::string & s,
- const bool w,
- const bool t,
- const bool f,
- bool & d
- ) :
- lists(l),
- colour(c),
- state(s),
- want_to_flush(w),
- this_failed(t),
- something_failed(f),
- done_summary(d)
+ std::string visit(const FetchJob & j) const
{
+ return "fetch " + stringify(*j.origin_id());
}
- void summary() const
+ std::string visit(const InstallJob & j) const
{
- if (! done_summary)
- cout << endl << c::bold_blue() << "Summary:" << c::normal() << endl << endl;
- done_summary = true;
+ return "install " + stringify(*j.origin_id()) + " to " + stringify(j.destination_repository_name());
}
- void visit(const SimpleInstallJob & job) const
+ std::string visit(const UninstallJob & j) const
{
- if (want_to_flush || something_failed)
- {
- summary();
- cout << colour << state << c::normal() << *job.changes_to_make_decision()->origin_id()
- << " to " << job.changes_to_make_decision()->destination()->repository() << endl;
- }
+ return "uninstall " + join(indirect_iterator(j.ids_to_remove()->begin()), indirect_iterator(j.ids_to_remove()->end()), ", ");
}
- void visit(const UninstallJob & job) const
- {
- if (want_to_flush || something_failed)
- {
- summary();
- cout << colour << state << c::normal() << "uninstall " << job.resolution()->resolvent() << endl;
- }
- }
-
- void visit(const FetchJob & job) const
- {
- if (want_to_flush || this_failed)
- {
- summary();
- cout << colour << state << c::normal() << "fetch " << *job.changes_to_make_decision()->origin_id() << endl;
- }
- }
+ };
- void visit(const ErrorJob &) const PALUDIS_ATTRIBUTE((noreturn))
- {
- throw InternalError(PALUDIS_HERE, "ErrorJob?");
- }
+ struct SummaryDisplayer
+ {
+ const std::tr1::shared_ptr<const ExecuteJob> job;
+ const bool something_failed;
+ bool & done_heading;
- void visit(const UsableJob &) const
+ SummaryDisplayer(const std::tr1::shared_ptr<const ExecuteJob> & j, const bool s, bool & b) :
+ job(j),
+ something_failed(s),
+ done_heading(b)
{
}
- void visit(const UsableGroupJob &) const
+ void need_heading() const
{
+ if (! done_heading)
+ {
+ done_heading = true;
+ cout << endl << c::bold_blue() << "Summary:" << c::normal() << endl << endl;
+ }
}
- };
-
- struct SummaryStateDisplayer
- {
- const ResolverLists & lists;
- const bool something_failed;
- bool & done_summary;
- SummaryStateDisplayer(const ResolverLists & l, const bool s, bool & d) :
- lists(l),
- something_failed(s),
- done_summary(d)
+ void visit(const JobActiveState &) const
{
+ need_heading();
+ cout << c::bold_yellow() << "pending: " << job->accept_returning<std::string>(SummaryNameVisitor()) << c::normal() << endl;
}
- void visit(const JobPendingState & state) const
+ void visit(const JobPendingState &) const
{
- state.job()->accept(SummaryJobNameDisplayer(lists, c::bold_normal(), "pending: ",
- false, false, something_failed, done_summary));
+ need_heading();
+ cout << c::bold_yellow() << "pending: " << job->accept_returning<std::string>(SummaryNameVisitor()) << c::normal() << endl;
}
- void visit(const JobSucceededState & state) const
+ void visit(const JobSucceededState & s) const
{
- state.job()->accept(SummaryJobNameDisplayer(lists, c::bold_green(), "succeeded: ",
- state.any_output_manager_wants_to_flush(), false, something_failed, done_summary));
+ if ((s.output_manager() && s.output_manager()->want_to_flush())
+ || (something_failed && ! simple_visitor_cast<const FetchJob>(*job)))
+ {
+ need_heading();
+ cout << c::bold_green() << "succeeded: " << job->accept_returning<std::string>(SummaryNameVisitor()) << c::normal() << endl;
+ }
}
- void visit(const JobSkippedState & state) const
+ void visit(const JobFailedState &) const
{
- state.job()->accept(SummaryJobNameDisplayer(lists, c::bold_yellow(), "skipped: ",
- false, false, something_failed, done_summary));
+ need_heading();
+ cout << c::bold_red() << "failed: " << job->accept_returning<std::string>(SummaryNameVisitor()) << c::normal() << endl;
}
- void visit(const JobFailedState & state) const
+ void visit(const JobSkippedState &) const
{
- state.job()->accept(SummaryJobNameDisplayer(lists, c::bold_red(), "failed: ",
- state.any_output_manager_wants_to_flush(), true, something_failed, done_summary));
+ if (! simple_visitor_cast<const FetchJob>(*job))
+ {
+ need_heading();
+ cout << c::bold_yellow() << "skipped: " << job->accept_returning<std::string>(SummaryNameVisitor()) << c::normal() << endl;
+ }
}
};
void display_summary(
- const ResolverLists & lists,
- Summary & summary,
+ const std::tr1::shared_ptr<JobLists> & lists,
const bool something_failed)
{
- bool done_summary(false);
- for (Summary::iterator s(summary.begin()), s_end(summary.end()) ;
- s != s_end ; )
- {
- const std::tr1::shared_ptr<JobState> state(*s);
- summary.erase(s++);
+ bool done_heading(false);
- state->accept(SummaryStateDisplayer(lists, something_failed, done_summary));
+ for (JobList<ExecuteJob>::ConstIterator c(lists->execute_job_list()->begin()),
+ c_end(lists->execute_job_list()->end()) ;
+ c != c_end ; ++c)
+ {
+ (*c)->state()->accept(SummaryDisplayer(*c, something_failed, done_heading));
+ (*c)->set_state(make_null_shared_ptr());
}
}
int execute_resolution(
const std::tr1::shared_ptr<Environment> & env,
- const ResolverLists & lists,
+ const std::tr1::shared_ptr<JobLists> & lists,
const ExecuteResolutionCommandLine & cmdline)
{
Context context("When executing chosen resolution:");
@@ -1322,15 +930,14 @@ namespace
).max_exit_status())
throw ActionAbortedError("Aborted by hook");
- Summary summary;
-
try
{
- retcode = execute_resolution_main(env, lists, cmdline, summary);
+ retcode = execute_resolution_main(env, lists, cmdline);
}
catch (...)
{
- display_summary(lists, summary, 0 != retcode);
+ if (! cmdline.a_pretend.specified())
+ display_summary(lists, 0 != retcode);
if (0 != env->perform_hook(Hook("install_task_execute_post")
("TARGETS", join(cmdline.begin_parameters(), cmdline.end_parameters(), " "))
@@ -1341,7 +948,8 @@ namespace
throw;
}
- display_summary(lists, summary, 0 != retcode);
+ if (! cmdline.a_pretend.specified())
+ display_summary(lists, 0 != retcode);
if (0 != env->perform_hook(Hook("install_task_execute_post")
("TARGETS", join(cmdline.begin_parameters(), cmdline.end_parameters(), " "))
@@ -1364,7 +972,7 @@ int
ExecuteResolutionCommand::run(
const std::tr1::shared_ptr<Environment> & env,
const std::tr1::shared_ptr<const Sequence<std::string > > & args,
- const std::tr1::shared_ptr<const ResolverLists> & maybe_lists
+ const std::tr1::shared_ptr<JobLists> & maybe_lists
)
{
ExecuteResolutionCommandLine cmdline;
@@ -1378,7 +986,7 @@ ExecuteResolutionCommand::run(
cmdline.import_options.apply(env);
- std::tr1::shared_ptr<const ResolverLists> lists(maybe_lists);
+ std::tr1::shared_ptr<JobLists> lists(maybe_lists);
if (! lists)
{
if (getenv_with_default("PALUDIS_SERIALISED_RESOLUTION_FD", "").empty())
@@ -1387,12 +995,12 @@ ExecuteResolutionCommand::run(
int fd(destringify<int>(getenv_with_default("PALUDIS_SERIALISED_RESOLUTION_FD", "")));
SafeIFStream deser_stream(fd);
Deserialiser deserialiser(env.get(), deser_stream);
- Deserialisation deserialisation("ResolverLists", deserialiser);
- lists = make_shared_copy(ResolverLists::deserialise(deserialisation));
+ Deserialisation deserialisation("JobLists", deserialiser);
+ lists = JobLists::deserialise(deserialisation);
close(fd);
}
- return execute_resolution(env, *lists, cmdline);
+ return execute_resolution(env, lists, cmdline);
}
int
diff --git a/src/clients/cave/cmd_execute_resolution.hh b/src/clients/cave/cmd_execute_resolution.hh
index 51f04cf..7ef3c28 100644
--- a/src/clients/cave/cmd_execute_resolution.hh
+++ b/src/clients/cave/cmd_execute_resolution.hh
@@ -21,7 +21,7 @@
#define PALUDIS_GUARD_SRC_CLIENTS_CAVE_CMD_EXECUTE_RESOLUTION_HH 1
#include "command.hh"
-#include <paludis/resolver/resolver_lists-fwd.hh>
+#include <paludis/resolver/job_lists-fwd.hh>
namespace paludis
{
@@ -41,7 +41,7 @@ namespace paludis
int run(
const std::tr1::shared_ptr<Environment> &,
const std::tr1::shared_ptr<const Sequence<std::string > > & args,
- const std::tr1::shared_ptr<const resolver::ResolverLists> & maybe_lists);
+ const std::tr1::shared_ptr<resolver::JobLists> & maybe_job_lists);
std::tr1::shared_ptr<args::ArgsHandler> make_doc_cmdline();
};
diff --git a/src/clients/cave/cmd_resolve_dump.cc b/src/clients/cave/cmd_resolve_dump.cc
index caf5a80..0dd42a1 100644
--- a/src/clients/cave/cmd_resolve_dump.cc
+++ b/src/clients/cave/cmd_resolve_dump.cc
@@ -25,10 +25,8 @@
#include <paludis/resolver/constraint.hh>
#include <paludis/resolver/decision.hh>
#include <paludis/resolver/reason.hh>
-#include <paludis/resolver/arrow.hh>
#include <paludis/resolver/destination.hh>
-#include <paludis/resolver/resolutions.hh>
-#include <paludis/resolver/resolver_lists.hh>
+#include <paludis/resolver/resolutions_by_resolvent.hh>
#include <paludis/util/enum_iterator.hh>
#include <paludis/util/indirect_iterator-impl.hh>
#include <paludis/util/join.hh>
@@ -191,14 +189,6 @@ namespace
return s;
}
- std::ostream &
- operator<< (std::ostream & s, const Arrow & a)
- {
- s << "Arrow(-> " << a.comes_after().string_id();
- s << ")";
- return s;
- }
-
std::string stringify_constraint(const Constraint & c)
{
std::stringstream s;
@@ -206,13 +196,6 @@ namespace
return s.str();
}
- std::string stringify_arrow(const Arrow & a)
- {
- std::stringstream s;
- s << a;
- return s.str();
- }
-
std::ostream &
operator<< (std::ostream & s, const Resolution & r)
{
@@ -237,8 +220,8 @@ namespace
{
std::cout << "Dumping resolutions by QPN:S:" << std::endl << std::endl;
- for (Resolutions::ConstIterator c(resolver->lists()->all_resolutions()->begin()),
- c_end(resolver->lists()->all_resolutions()->end()) ;
+ for (ResolutionsByResolvent::ConstIterator c(resolver->resolved()->resolutions_by_resolvent()->begin()),
+ c_end(resolver->resolved()->resolutions_by_resolvent()->end()) ;
c != c_end ; ++c)
{
std::cout << (*c)->resolvent() << std::endl;
diff --git a/src/clients/cave/continue_on_failure_TEST b/src/clients/cave/continue_on_failure_TEST
new file mode 100755
index 0000000..50e0b88
--- /dev/null
+++ b/src/clients/cave/continue_on_failure_TEST
@@ -0,0 +1,56 @@
+#!/usr/bin/env bash
+
+export PALUDIS_HOME=`pwd`/continue_on_failure_TEST_dir/config/
+export TEST_ROOT=`pwd`/continue_on_failure_TEST_dir/root/
+
+./cave --environment :continue-on-failure-test \
+ resolve -x --continue-on-failure if-satisfied a b c
+
+if [[ -f continue_on_failure_TEST_dir/root/a ]] ; then
+ exit 1
+fi
+
+if [[ -f continue_on_failure_TEST_dir/root/b ]] ; then
+ exit 2
+fi
+
+if ! [[ -f continue_on_failure_TEST_dir/root/c ]] ; then
+ exit 3
+fi
+
+if [[ -f continue_on_failure_TEST_dir/root/d ]] ; then
+ exit 4
+fi
+
+if ! [[ -f continue_on_failure_TEST_dir/root/e ]] ; then
+ exit 5
+fi
+
+./cave --environment :continue-on-failure-test \
+ resolve -x =cat/w-1 cat/u --permit-old-version '*/*' || exit 6
+
+./cave --environment :continue-on-failure-test \
+ resolve -x --continue-on-failure if-independent x y z
+
+if [[ -f continue_on_failure_TEST_dir/root/z ]] ; then
+ exit 7
+fi
+
+if [[ -f continue_on_failure_TEST_dir/root/y ]] ; then
+ exit 8
+fi
+
+if ! [[ -f continue_on_failure_TEST_dir/root/x ]] ; then
+ exit 9
+fi
+
+if [[ -f continue_on_failure_TEST_dir/root/w ]] ; then
+ exit 10
+fi
+
+if ! [[ -f continue_on_failure_TEST_dir/root/v ]] ; then
+ exit 11
+fi
+
+exit 0
+
diff --git a/src/clients/cave/continue_on_failure_TEST_cleanup.sh b/src/clients/cave/continue_on_failure_TEST_cleanup.sh
new file mode 100755
index 0000000..5304541
--- /dev/null
+++ b/src/clients/cave/continue_on_failure_TEST_cleanup.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+# vim: set ft=sh sw=4 sts=4 et :
+
+if [ -d continue_on_failure_TEST_dir ] ; then
+ rm -fr continue_on_failure_TEST_dir
+else
+ true
+fi
+
diff --git a/src/clients/cave/continue_on_failure_TEST_setup.sh b/src/clients/cave/continue_on_failure_TEST_setup.sh
new file mode 100755
index 0000000..4ae8670
--- /dev/null
+++ b/src/clients/cave/continue_on_failure_TEST_setup.sh
@@ -0,0 +1,257 @@
+#!/usr/bin/env bash
+# vim: set ft=sh sw=4 sts=4 et :
+
+mkdir continue_on_failure_TEST_dir || exit 1
+cd continue_on_failure_TEST_dir || exit 1
+mkdir -p build
+
+mkdir -p config/.paludis-continue-on-failure-test/repositories
+cat <<END > config/.paludis-continue-on-failure-test/specpath.conf
+config-suffix =
+END
+
+cat <<END > config/.paludis-continue-on-failure-test/use.conf
+*/* foo
+END
+
+cat <<END > config/.paludis-continue-on-failure-test/licenses.conf
+*/* *
+END
+
+cat <<END > config/.paludis-continue-on-failure-test/keywords.conf
+*/* test
+END
+
+cat <<END > config/.paludis-continue-on-failure-test/general.conf
+world = `pwd`/root/world
+END
+
+cat <<END > config/.paludis-continue-on-failure-test/bashrc
+export CHOST="my-chost"
+END
+
+cat <<END > config/.paludis-continue-on-failure-test/repositories/repo1.conf
+location = `pwd`/repo1
+cache = /var/empty
+format = ebuild
+names_cache = /var/empty
+profiles = \${location}/profiles/testprofile
+builddir = `pwd`/build
+END
+
+cat <<END > config/.paludis-continue-on-failure-test/repositories/installed.conf
+location = `pwd`/root/var/db/pkg
+format = vdb
+names_cache = /var/empty
+provides_cache = /var/empty
+builddir = `pwd`/build
+END
+
+mkdir -p root/tmp
+mkdir -p root/var/db/pkg
+mkdir -p root/${SYSCONFDIR}
+touch root/${SYSCONFDIR}/ld.so.conf
+
+mkdir -p repo1/{eclass,distfiles,profiles/testprofile,cat/{a,b,c,d,e,u,v,w,x,y,z}/files} || exit 1
+
+cd repo1 || exit 1
+echo "test-repo-1" > profiles/repo_name || exit 1
+cat <<END > profiles/categories || exit 1
+cat
+END
+cat <<END > profiles/testprofile/make.defaults
+ARCH=test
+USERLAND=test
+KERNEL=test
+TESTPROFILE_WAS_SOURCED=yes
+PROFILE_ORDERING=1
+USE_EXPAND="USERLAND KERNEL"
+END
+
+cat <<"END" > cat/a/a-1.ebuild || exit 1
+DESCRIPTION="Test a"
+HOMEPAGE="http://paludis.pioto.org/"
+SRC_URI=""
+SLOT="0"
+IUSE=""
+LICENSE="GPL-2"
+KEYWORDS="test"
+RDEPEND="cat/d"
+
+src_install() {
+ mkdir -p ${D}${TEST_ROOT}
+ touch ${D}${TEST_ROOT}/a
+}
+END
+
+cat <<"END" > cat/b/b-1.ebuild || exit 1
+DESCRIPTION="Test b"
+HOMEPAGE="http://paludis.pioto.org/"
+SRC_URI=""
+SLOT="0"
+IUSE=""
+LICENSE="GPL-2"
+KEYWORDS="test"
+RDEPEND="cat/a"
+
+src_install() {
+ mkdir -p ${D}${TEST_ROOT}
+ touch ${D}${TEST_ROOT}/b
+}
+END
+
+cat <<"END" > cat/c/c-1.ebuild || exit 1
+DESCRIPTION="Test c"
+HOMEPAGE="http://paludis.pioto.org/"
+SRC_URI=""
+SLOT="0"
+IUSE=""
+LICENSE="GPL-2"
+KEYWORDS="test"
+RDEPEND="cat/e"
+
+src_install() {
+ mkdir -p ${D}${TEST_ROOT}
+ touch ${D}${TEST_ROOT}/c
+}
+END
+
+cat <<"END" > cat/d/d-1.ebuild || exit 1
+DESCRIPTION="Test d"
+HOMEPAGE="http://paludis.pioto.org/"
+SRC_URI=""
+SLOT="0"
+IUSE=""
+LICENSE="GPL-2"
+KEYWORDS="test"
+RDEPEND=""
+
+pkg_setup() {
+ die "supposed to fail"
+}
+END
+
+cat <<"END" > cat/e/e-1.ebuild || exit 1
+DESCRIPTION="Test e"
+HOMEPAGE="http://paludis.pioto.org/"
+SRC_URI=""
+SLOT="0"
+IUSE=""
+LICENSE="GPL-2"
+KEYWORDS="test"
+RDEPEND=""
+
+src_install() {
+ mkdir -p ${D}${TEST_ROOT}
+ touch ${D}${TEST_ROOT}/e
+}
+END
+
+cat <<"END" > cat/z/z-1.ebuild || exit 1
+DESCRIPTION="Test z"
+HOMEPAGE="http://paludis.pioto.org/"
+SRC_URI=""
+SLOT="0"
+IUSE=""
+LICENSE="GPL-2"
+KEYWORDS="test"
+RDEPEND="cat/w"
+
+src_install() {
+ mkdir -p ${D}${TEST_ROOT}
+ touch ${D}${TEST_ROOT}/z
+}
+END
+
+cat <<"END" > cat/y/y-1.ebuild || exit 1
+DESCRIPTION="Test y"
+HOMEPAGE="http://paludis.pioto.org/"
+SRC_URI=""
+SLOT="0"
+IUSE=""
+LICENSE="GPL-2"
+KEYWORDS="test"
+RDEPEND="cat/u"
+
+src_install() {
+ mkdir -p ${D}${TEST_ROOT}
+ touch ${D}${TEST_ROOT}/y
+}
+END
+
+cat <<"END" > cat/x/x-1.ebuild || exit 1
+DESCRIPTION="Test x"
+HOMEPAGE="http://paludis.pioto.org/"
+SRC_URI=""
+SLOT="0"
+IUSE=""
+LICENSE="GPL-2"
+KEYWORDS="test"
+RDEPEND="cat/v"
+
+src_install() {
+ mkdir -p ${D}${TEST_ROOT}
+ touch ${D}${TEST_ROOT}/x
+}
+END
+
+cat <<"END" > cat/w/w-1.ebuild || exit 1
+DESCRIPTION="Test w"
+HOMEPAGE="http://paludis.pioto.org/"
+SRC_URI=""
+SLOT="0"
+IUSE=""
+LICENSE="GPL-2"
+KEYWORDS="test"
+RDEPEND=""
+END
+
+cat <<"END" > cat/w/w-2.ebuild || exit 1
+DESCRIPTION="Test w"
+HOMEPAGE="http://paludis.pioto.org/"
+SRC_URI=""
+SLOT="0"
+IUSE=""
+LICENSE="GPL-2"
+KEYWORDS="test"
+RDEPEND=""
+
+pkg_setup() {
+ die "supposed to fail"
+}
+END
+
+cat <<"END" > cat/v/v-1.ebuild || exit 1
+DESCRIPTION="Test v"
+HOMEPAGE="http://paludis.pioto.org/"
+SRC_URI=""
+SLOT="0"
+IUSE=""
+LICENSE="GPL-2"
+KEYWORDS="test"
+RDEPEND=""
+
+src_install() {
+ mkdir -p ${D}${TEST_ROOT}
+ touch ${D}${TEST_ROOT}/v
+}
+END
+
+cat <<"END" > cat/u/u-1.ebuild || exit 1
+DESCRIPTION="Test u"
+HOMEPAGE="http://paludis.pioto.org/"
+SRC_URI=""
+SLOT="0"
+IUSE=""
+LICENSE="GPL-2"
+KEYWORDS="test"
+RDEPEND="cat/w"
+
+src_install() {
+ mkdir -p ${D}${TEST_ROOT}
+ touch ${D}${TEST_ROOT}/u
+}
+END
+
+cd ..
+
diff --git a/src/clients/cave/resolve_common.cc b/src/clients/cave/resolve_common.cc
index 8364e77..d8c8ca5 100644
--- a/src/clients/cave/resolve_common.cc
+++ b/src/clients/cave/resolve_common.cc
@@ -50,9 +50,10 @@
#include <paludis/resolver/resolvent.hh>
#include <paludis/resolver/constraint.hh>
#include <paludis/resolver/sanitised_dependencies.hh>
-#include <paludis/resolver/resolutions.hh>
-#include <paludis/resolver/resolver_lists.hh>
+#include <paludis/resolver/resolutions_by_resolvent.hh>
#include <paludis/resolver/required_confirmations.hh>
+#include <paludis/resolver/job_lists.hh>
+#include <paludis/resolver/decisions.hh>
#include <paludis/user_dep_spec.hh>
#include <paludis/notifier_callback.hh>
#include <paludis/generator.hh>
@@ -486,7 +487,7 @@ namespace
const ResolveCommandLineResolutionOptions & resolution_options,
const PackageDepSpecList & without,
const PackageDepSpecList & with,
- const Resolvent &,
+ const std::tr1::shared_ptr<const Resolution> &,
const PackageDepSpec & spec,
const std::tr1::shared_ptr<const Reason> & reason)
{
@@ -839,7 +840,6 @@ namespace
const PackageDepSpecList & ignore_from,
const PackageDepSpecList & no_blockers_from,
const PackageDepSpecList & no_dependencies_from,
- const Resolvent & resolvent,
const std::tr1::shared_ptr<const Resolution> & resolution,
const SanitisedDependency & dep)
{
@@ -862,7 +862,7 @@ namespace
for (PackageDepSpecList::const_iterator l(take_from.begin()), l_end(take_from.end()) ;
l != l_end ; ++l)
{
- if (match_qpns(*env, *l, resolvent.package()))
+ if (match_qpns(*env, *l, resolution->resolvent().package()))
return si_take;
}
@@ -877,7 +877,7 @@ namespace
for (PackageDepSpecList::const_iterator l(ignore_from.begin()), l_end(ignore_from.end()) ;
l != l_end ; ++l)
{
- if (match_qpns(*env, *l, resolvent.package()))
+ if (match_qpns(*env, *l, resolution->resolvent().package()))
return si_ignore;
}
@@ -917,8 +917,7 @@ namespace
const std::tr1::shared_ptr<const Repository>
find_repository_for_fn(const Environment * const env,
const ResolveCommandLineResolutionOptions &,
- const Resolvent & resolvent,
- const std::tr1::shared_ptr<const Resolution> &,
+ const std::tr1::shared_ptr<const Resolution> & resolution,
const ChangesToMakeDecision & decision)
{
std::tr1::shared_ptr<const Repository> result;
@@ -926,7 +925,7 @@ namespace
r_end(env->package_database()->end_repositories()) ;
r != r_end ; ++r)
{
- switch (resolvent.destination_type())
+ switch (resolution->resolvent().destination_type())
{
case dt_install_to_slash:
if ((! (*r)->installed_root_key()) || ((*r)->installed_root_key()->value() != FSEntry("/")))
@@ -947,7 +946,7 @@ namespace
{
if (result)
throw ConfigurationError("For '" + stringify(*decision.origin_id())
- + "' with destination type " + stringify(resolvent.destination_type())
+ + "' with destination type " + stringify(resolution->resolvent().destination_type())
+ ", don't know whether to install to ::" + stringify(result->name())
+ " or ::" + stringify((*r)->name()));
else
@@ -957,7 +956,7 @@ namespace
if (! result)
throw ConfigurationError("No repository suitable for '" + stringify(*decision.origin_id())
- + "' with destination type " + stringify(resolvent.destination_type()) + " has been configured");
+ + "' with destination type " + stringify(resolution->resolvent().destination_type()) + " has been configured");
return result;
}
@@ -1135,7 +1134,6 @@ namespace
const ResolveCommandLineResolutionOptions & resolution_options,
const PackageDepSpecList & permit_downgrade,
const PackageDepSpecList & permit_old_version,
- const Resolvent &,
const std::tr1::shared_ptr<const Resolution> & r,
const std::tr1::shared_ptr<const RequiredConfirmation> & c)
{
@@ -1147,7 +1145,6 @@ namespace
const std::tr1::shared_ptr<ConstraintSequence> get_constraints_for_dependent_fn(
const Environment * const env,
const PackageDepSpecList & list,
- const Resolvent &,
const std::tr1::shared_ptr<const Resolution> &,
const std::tr1::shared_ptr<const PackageID> & id,
const std::tr1::shared_ptr<const PackageIDSequence> & ids)
@@ -1185,16 +1182,16 @@ namespace
return result;
}
- void ser_thread_func(StringListStream & ser_stream, const ResolverLists & resolution_lists)
+ void serialise_resolved(StringListStream & ser_stream, const Resolved & resolved)
{
Serialiser ser(ser_stream);
- resolution_lists.serialise(ser);
+ resolved.serialise(ser);
ser_stream.nothing_more_to_write();
}
int display_resolution(
const std::tr1::shared_ptr<Environment> & env,
- const std::tr1::shared_ptr<const ResolverLists> & resolution_lists,
+ const std::tr1::shared_ptr<const Resolved> & resolved,
const ResolveCommandLineResolutionOptions &,
const ResolveCommandLineDisplayOptions & display_options,
const ResolveCommandLineProgramOptions & program_options,
@@ -1204,9 +1201,9 @@ namespace
Context context("When displaying chosen resolution:");
StringListStream ser_stream;
- Thread ser_thread(std::tr1::bind(&ser_thread_func,
+ Thread ser_thread(std::tr1::bind(&serialise_resolved,
std::tr1::ref(ser_stream),
- std::tr1::cref(*resolution_lists)));
+ std::tr1::cref(*resolved)));
std::tr1::shared_ptr<Sequence<std::string> > args(new Sequence<std::string>);
@@ -1250,12 +1247,19 @@ namespace
return run_command(cmd);
}
else
- return DisplayResolutionCommand().run(env, args, resolution_lists);
+ return DisplayResolutionCommand().run(env, args, resolved);
+ }
+
+ void serialise_job_lists(StringListStream & ser_stream, const JobLists & job_lists)
+ {
+ Serialiser ser(ser_stream);
+ job_lists.serialise(ser);
+ ser_stream.nothing_more_to_write();
}
int perform_resolution(
const std::tr1::shared_ptr<Environment> & env,
- const std::tr1::shared_ptr<const ResolverLists> & resolution_lists,
+ const std::tr1::shared_ptr<const Resolved> & resolved,
const ResolveCommandLineResolutionOptions & resolution_options,
const ResolveCommandLineExecutionOptions & execution_options,
const ResolveCommandLineProgramOptions & program_options,
@@ -1307,7 +1311,7 @@ namespace
* be a fun exercise for someone with way too much time on their hands.
* */
StringListStream ser_stream;
- ser_thread_func(ser_stream, *resolution_lists);
+ serialise_job_lists(ser_stream, *resolved->job_lists());
std::string command;
if (program_options.a_execute_resolution_program.specified())
@@ -1335,7 +1339,7 @@ namespace
become_command(cmd);
}
else
- return ExecuteResolutionCommand().run(env, args, resolution_lists);
+ return ExecuteResolutionCommand().run(env, args, resolved->job_lists());
}
struct KindNameVisitor
@@ -1605,11 +1609,11 @@ paludis::cave::resolve_common(
env.get(), std::tr1::cref(allowed_to_remove_specs), _1),
n::confirm_fn() = std::tr1::bind(&confirm_fn,
env.get(), std::tr1::cref(resolution_options), std::tr1::cref(permit_downgrade),
- std::tr1::cref(permit_old_version), _1, _2, _3),
+ std::tr1::cref(permit_old_version), _1, _2),
n::find_repository_for_fn() = std::tr1::bind(&find_repository_for_fn,
- env.get(), std::tr1::cref(resolution_options), _1, _2, _3),
+ env.get(), std::tr1::cref(resolution_options), _1, _2),
n::get_constraints_for_dependent_fn() = std::tr1::bind(&get_constraints_for_dependent_fn,
- env.get(), std::tr1::cref(less_restrictive_remove_blockers_specs), _1, _2, _3, _4),
+ env.get(), std::tr1::cref(less_restrictive_remove_blockers_specs), _1, _2, _3),
n::get_destination_types_for_fn() = std::tr1::bind(&get_destination_types_for_fn,
env.get(), std::tr1::cref(resolution_options), _1, _2, _3),
n::get_initial_constraints_for_fn() = std::tr1::bind(&initial_constraints_for_fn,
@@ -1622,7 +1626,7 @@ paludis::cave::resolve_common(
n::interest_in_spec_fn() = std::tr1::bind(&interest_in_spec_fn,
env.get(), std::tr1::cref(resolution_options), std::tr1::cref(take), std::tr1::cref(take_from),
std::tr1::cref(ignore), std::tr1::cref(ignore_from), std::tr1::cref(no_blockers_from),
- std::tr1::cref(no_dependencies_from), _1, _2, _3),
+ std::tr1::cref(no_dependencies_from), _1, _2),
n::make_destination_filtered_generator_fn() = std::tr1::bind(&make_destination_filtered_generator,
env.get(), std::tr1::cref(resolution_options), all_binary_repos_generator, _1, _2),
n::prefer_or_avoid_fn() = std::tr1::bind(&prefer_or_avoid_fn,
@@ -1674,17 +1678,17 @@ paludis::cave::resolve_common(
dump_if_requested(env, resolver, resolution_options);
- retcode |= display_resolution(env, resolver->lists(), resolution_options,
+ retcode |= display_resolution(env, resolver->resolved(), resolution_options,
display_options, program_options, keys_if_import, targets);
- if (! resolver->lists()->taken_error_job_ids()->empty())
+ if (! resolver->resolved()->taken_unable_to_make_decisions()->empty())
retcode |= 1;
- if (! resolver->lists()->job_ids_needing_confirmation()->empty())
+ if (! resolver->resolved()->taken_unconfirmed_change_or_remove_decisions()->empty())
retcode |= 3;
if (0 == retcode)
- return perform_resolution(env, resolver->lists(), resolution_options,
+ return perform_resolution(env, resolver->resolved(), resolution_options,
execution_options, program_options, keys_if_import, targets, is_set);
}
catch (...)