aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-01-25 18:35:58 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-01-25 18:35:58 +0000
commit5392e5995fd3cdc6b24ef081b7662cfc4f1eb4d7 (patch)
tree601c0c1cc44aec1341067cdcc48eb819dfe7d886
parent5c626b9ecb68be1171d4769a016ae6ea7c1f7f2e (diff)
parentf91f8744cdc3d0517aee34e7b393b44280375734 (diff)
downloadpaludis-5392e5995fd3cdc6b24ef081b7662cfc4f1eb4d7.tar.gz
paludis-5392e5995fd3cdc6b24ef081b7662cfc4f1eb4d7.tar.xz
Merge branch 'cleaner-jobs'
-rw-r--r--.gitignore1
-rw-r--r--paludis/resolver/Makefile.am2
-rw-r--r--paludis/resolver/decision.cc38
-rw-r--r--paludis/resolver/decision.hh8
-rw-r--r--paludis/resolver/job-fwd.hh7
-rw-r--r--paludis/resolver/job.cc299
-rw-r--r--paludis/resolver/job.hh106
-rw-r--r--paludis/resolver/job_id.cc8
-rw-r--r--paludis/resolver/job_id.hh3
-rw-r--r--paludis/resolver/job_state-fwd.hh35
-rw-r--r--paludis/resolver/job_state.cc180
-rw-r--r--paludis/resolver/job_state.hh114
-rw-r--r--paludis/resolver/jobs.cc68
-rw-r--r--paludis/resolver/jobs.hh6
-rw-r--r--paludis/resolver/orderer.cc231
-rw-r--r--paludis/resolver/orderer.hh5
-rw-r--r--paludis/resolver/resolver.cc8
-rw-r--r--paludis/resolver/resolver_TEST_any.cc42
-rw-r--r--paludis/resolver/resolver_TEST_blockers.cc15
-rw-r--r--paludis/resolver/resolver_TEST_cycles.cc41
-rw-r--r--paludis/resolver/resolver_TEST_serialisation.cc15
-rw-r--r--paludis/resolver/resolver_TEST_simple.cc30
-rw-r--r--paludis/resolver/resolver_TEST_suggestions.cc44
-rw-r--r--paludis/resolver/resolver_TEST_virtuals.cc28
-rw-r--r--paludis/resolver/resolver_lists.cc33
-rw-r--r--paludis/resolver/resolver_lists.hh14
-rw-r--r--paludis/resolver/resolver_test.cc13
-rw-r--r--src/clients/cave/cmd_display_resolution.cc284
-rw-r--r--src/clients/cave/cmd_execute_resolution.cc672
-rw-r--r--src/clients/cave/cmd_resolve_cmdline.cc16
-rw-r--r--src/clients/cave/resolve_common.cc2
31 files changed, 1562 insertions, 806 deletions
diff --git a/.gitignore b/.gitignore
index f8c4d4d..ae04456 100644
--- a/.gitignore
+++ b/.gitignore
@@ -336,6 +336,7 @@ paludis-*.*.*.tar.bz2
/paludis/syncers/dobzr+ftp
/paludis/syncers/dobzr+http
/paludis/syncers/dobzr+https
+/paludis/syncers/dobzr+lp
/paludis/syncers/dobzr+sftp
/paludis/syncers/dobzr+ssh
/paludis/syncers/docvs+ext
diff --git a/paludis/resolver/Makefile.am b/paludis/resolver/Makefile.am
index e3c5a7b..f479e56 100644
--- a/paludis/resolver/Makefile.am
+++ b/paludis/resolver/Makefile.am
@@ -27,6 +27,7 @@ noinst_HEADERS = \
constraint.hh constraint-fwd.hh \
job.hh job-fwd.hh \
job_id.hh job_id-fwd.hh \
+ job_state.hh job_state-fwd.hh \
jobs.hh jobs-fwd.hh \
decider.hh decider-fwd.hh \
decision.hh decision-fwd.hh \
@@ -59,6 +60,7 @@ libpaludisresolver_a_SOURCES = \
failure_kinds.cc \
job.cc \
job_id.cc \
+ job_state.cc \
jobs.cc \
orderer.cc \
reason.cc \
diff --git a/paludis/resolver/decision.cc b/paludis/resolver/decision.cc
index d019247..c27a7cf 100644
--- a/paludis/resolver/decision.cc
+++ b/paludis/resolver/decision.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009 Ciaran McCreesh
+ * 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
@@ -62,27 +62,11 @@ Decision::deserialise(Deserialisation & d)
}
else if (d.class_name() == "ChangesToMakeDecision")
{
- Deserialisator v(d, "ChangesToMakeDecision");
- return make_shared_ptr(new ChangesToMakeDecision(
- v.member<std::tr1::shared_ptr<const PackageID> >("origin_id"),
- v.member<bool>("best"),
- v.member<bool>("taken"),
- v.member<std::tr1::shared_ptr<const Destination> >("destination")
- ));
+ return ChangesToMakeDecision::deserialise(d);
}
else if (d.class_name() == "UnableToMakeDecision")
{
- Deserialisator v(d, "UnableToMakeDecision");
-
- std::tr1::shared_ptr<UnsuitableCandidates> unsuitable_candidates(new UnsuitableCandidates);
- Deserialisator vv(*v.find_remove_member("unsuitable_candidates"), "c");
- for (int n(1), n_end(vv.member<int>("count") + 1) ; n != n_end ; ++n)
- unsuitable_candidates->push_back(vv.member<UnsuitableCandidate>(stringify(n)));
-
- return make_shared_ptr(new UnableToMakeDecision(
- unsuitable_candidates,
- v.member<bool>("taken")
- ));
+ return UnableToMakeDecision::deserialise(d);
}
else
throw InternalError(PALUDIS_HERE, "unknown class '" + stringify(d.class_name()) + "'");
@@ -100,6 +84,22 @@ ChangesToMakeDecision::deserialise(Deserialisation & d)
));
}
+const std::tr1::shared_ptr<UnableToMakeDecision>
+UnableToMakeDecision::deserialise(Deserialisation & d)
+{
+ Deserialisator v(d, "UnableToMakeDecision");
+
+ std::tr1::shared_ptr<UnsuitableCandidates> unsuitable_candidates(new UnsuitableCandidates);
+ Deserialisator vv(*v.find_remove_member("unsuitable_candidates"), "c");
+ for (int n(1), n_end(vv.member<int>("count") + 1) ; n != n_end ; ++n)
+ unsuitable_candidates->push_back(vv.member<UnsuitableCandidate>(stringify(n)));
+
+ return make_shared_ptr(new UnableToMakeDecision(
+ unsuitable_candidates,
+ v.member<bool>("taken")
+ ));
+}
+
namespace paludis
{
template <>
diff --git a/paludis/resolver/decision.hh b/paludis/resolver/decision.hh
index 95c5da5..026aace 100644
--- a/paludis/resolver/decision.hh
+++ b/paludis/resolver/decision.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009 Ciaran McCreesh
+ * 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
@@ -126,7 +126,8 @@ namespace paludis
class PALUDIS_VISIBLE UnableToMakeDecision :
public Decision,
public ImplementAcceptMethods<Decision, UnableToMakeDecision>,
- private PrivateImplementationPattern<UnableToMakeDecision>
+ private PrivateImplementationPattern<UnableToMakeDecision>,
+ public std::tr1::enable_shared_from_this<UnableToMakeDecision>
{
public:
UnableToMakeDecision(
@@ -139,6 +140,9 @@ namespace paludis
virtual void serialise(Serialiser &) const;
const std::tr1::shared_ptr<const UnsuitableCandidates> unsuitable_candidates() const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ static const std::tr1::shared_ptr<UnableToMakeDecision> deserialise(
+ Deserialisation & d) PALUDIS_ATTRIBUTE((warn_unused_result));
};
}
diff --git a/paludis/resolver/job-fwd.hh b/paludis/resolver/job-fwd.hh
index 0f88e1b..e9ea4da 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 Ciaran McCreesh
+ * 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
@@ -27,11 +27,10 @@ namespace paludis
struct Job;
struct SimpleInstallJob;
- struct PretendJob;
struct FetchJob;
struct UsableJob;
- struct SyncPointJob;
- struct UntakenInstallJob;
+ struct UsableGroupJob;
+ struct ErrorJob;
}
}
diff --git a/paludis/resolver/job.cc b/paludis/resolver/job.cc
index d09e1f4..03d3ea1 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 Ciaran McCreesh
+ * 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
@@ -26,6 +26,7 @@
#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>
using namespace paludis;
@@ -38,26 +39,27 @@ namespace paludis
{
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;
Implementation(const std::tr1::shared_ptr<const Resolution> & r) :
resolution(r),
- arrows(new ArrowSequence)
+ arrows(new ArrowSequence),
+ used_existing_packages_when_ordering(new JobIDSequence)
{
}
};
template <>
- struct Implementation<PretendJob>
+ struct Implementation<UsableGroupJob>
{
- const std::tr1::shared_ptr<const Resolution> resolution;
- const std::tr1::shared_ptr<const ChangesToMakeDecision> decision;
+ 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;
- Implementation(const std::tr1::shared_ptr<const Resolution> & r,
- const std::tr1::shared_ptr<const ChangesToMakeDecision> & d) :
- resolution(r),
- decision(d),
- arrows(new ArrowSequence)
+ Implementation(const std::tr1::shared_ptr<const JobIDSequence> & i) :
+ ids(i),
+ arrows(new ArrowSequence),
+ used_existing_packages_when_ordering(new JobIDSequence)
{
}
};
@@ -68,12 +70,14 @@ namespace paludis
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;
Implementation(const std::tr1::shared_ptr<const Resolution> & r,
const std::tr1::shared_ptr<const ChangesToMakeDecision> & d) :
resolution(r),
decision(d),
- arrows(new ArrowSequence)
+ arrows(new ArrowSequence),
+ used_existing_packages_when_ordering(new JobIDSequence)
{
}
};
@@ -84,38 +88,32 @@ namespace paludis
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;
Implementation(const std::tr1::shared_ptr<const Resolution> & r,
const std::tr1::shared_ptr<const ChangesToMakeDecision> & d) :
resolution(r),
decision(d),
- arrows(new ArrowSequence)
+ arrows(new ArrowSequence),
+ used_existing_packages_when_ordering(new JobIDSequence)
{
}
};
template <>
- struct Implementation<UntakenInstallJob>
+ 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;
- Implementation(const std::tr1::shared_ptr<const Resolution> & r) :
+ Implementation(const std::tr1::shared_ptr<const Resolution> & r,
+ const std::tr1::shared_ptr<const UnableToMakeDecision> & d) :
resolution(r),
- arrows(new ArrowSequence)
- {
- }
- };
-
- template <>
- struct Implementation<SyncPointJob>
- {
- const SyncPoint sync_point;
- const std::tr1::shared_ptr<ArrowSequence> arrows;
-
- Implementation(const SyncPoint s) :
- sync_point(s),
- arrows(new ArrowSequence)
+ decision(d),
+ arrows(new ArrowSequence),
+ used_existing_packages_when_ordering(new JobIDSequence)
{
}
};
@@ -135,6 +133,15 @@ namespace
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)));
+ }
}
const std::tr1::shared_ptr<Job>
@@ -149,24 +156,30 @@ Job::deserialise(Deserialisation & d)
v.member<std::tr1::shared_ptr<Resolution> >("resolution")
));
do_arrows(result, v);
+ do_existing(result, v);
}
- else if (d.class_name() == "SimpleInstallJob")
+ else if (d.class_name() == "UsableGroupJob")
{
- Deserialisator v(d, "SimpleInstallJob");
- result.reset(new SimpleInstallJob(
- v.member<std::tr1::shared_ptr<Resolution> >("resolution"),
- v.member<std::tr1::shared_ptr<ChangesToMakeDecision> >("decision")
- ));
+ 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);
}
- else if (d.class_name() == "PretendJob")
+ else if (d.class_name() == "SimpleInstallJob")
{
- Deserialisator v(d, "PretendJob");
- result.reset(new PretendJob(
+ Deserialisator v(d, "SimpleInstallJob");
+ result.reset(new SimpleInstallJob(
v.member<std::tr1::shared_ptr<Resolution> >("resolution"),
v.member<std::tr1::shared_ptr<ChangesToMakeDecision> >("decision")
));
do_arrows(result, v);
+ do_existing(result, v);
}
else if (d.class_name() == "FetchJob")
{
@@ -176,22 +189,17 @@ Job::deserialise(Deserialisation & d)
v.member<std::tr1::shared_ptr<ChangesToMakeDecision> >("decision")
));
do_arrows(result, v);
+ do_existing(result, v);
}
- else if (d.class_name() == "UntakenInstallJob")
- {
- Deserialisator v(d, "UntakenInstallJob");
- result.reset(new UntakenInstallJob(
- v.member<std::tr1::shared_ptr<Resolution> >("resolution")
- ));
- do_arrows(result, v);
- }
- else if (d.class_name() == "SyncPointJob")
+ else if (d.class_name() == "ErrorJob")
{
- Deserialisator v(d, "SyncPointJob");
- result.reset(new SyncPointJob(
- destringify<SyncPoint>(v.member<std::string>("sync_point"))
+ Deserialisator v(d, "ErrorJob");
+ result.reset(new ErrorJob(
+ v.member<std::tr1::shared_ptr<Resolution> >("resolution"),
+ v.member<std::tr1::shared_ptr<UnableToMakeDecision> >("decision")
));
do_arrows(result, v);
+ do_existing(result, v);
}
else
throw InternalError(PALUDIS_HERE, "unknown class '" + stringify(d.class_name()) + "'");
@@ -214,12 +222,30 @@ UsableJob::resolution() const
return _imp->resolution;
}
-const std::tr1::shared_ptr<ArrowSequence>
+const std::tr1::shared_ptr<const ArrowSequence>
UsableJob::arrows() const
{
return _imp->arrows;
}
+const std::tr1::shared_ptr<ArrowSequence>
+UsableJob::arrows()
+{
+ return _imp->arrows;
+}
+
+const std::tr1::shared_ptr<const JobIDSequence>
+UsableJob::used_existing_packages_when_ordering() const
+{
+ return _imp->used_existing_packages_when_ordering;
+}
+
+const std::tr1::shared_ptr<JobIDSequence>
+UsableJob::used_existing_packages_when_ordering()
+{
+ return _imp->used_existing_packages_when_ordering;
+}
+
const JobID
UsableJob::id() const
{
@@ -234,52 +260,74 @@ 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>(),
+ "used_existing_packages_when_ordering", used_existing_packages_when_ordering())
;
}
-PretendJob::PretendJob(const std::tr1::shared_ptr<const Resolution> & r,
- const std::tr1::shared_ptr<const ChangesToMakeDecision> & d) :
- PrivateImplementationPattern<PretendJob>(new Implementation<PretendJob>(r, d))
+UsableGroupJob::UsableGroupJob(const std::tr1::shared_ptr<const JobIDSequence> & r) :
+ PrivateImplementationPattern<UsableGroupJob>(new Implementation<UsableGroupJob>(r))
{
}
-PretendJob::~PretendJob()
+UsableGroupJob::~UsableGroupJob()
{
}
-const std::tr1::shared_ptr<const Resolution>
-PretendJob::resolution() const
+const std::tr1::shared_ptr<const JobIDSequence>
+UsableGroupJob::job_ids() const
{
- return _imp->resolution;
+ return _imp->ids;
}
-const std::tr1::shared_ptr<const ChangesToMakeDecision>
-PretendJob::decision() const
+const std::tr1::shared_ptr<const ArrowSequence>
+UsableGroupJob::arrows() const
{
- return _imp->decision;
+ return _imp->arrows;
}
const std::tr1::shared_ptr<ArrowSequence>
-PretendJob::arrows() const
+UsableGroupJob::arrows()
{
return _imp->arrows;
}
+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;
+}
+
+namespace
+{
+ std::string stringify_job_id(const JobID & i)
+ {
+ return i.string_id();
+ }
+}
+
const JobID
-PretendJob::id() const
+UsableGroupJob::id() const
{
return make_named_values<JobID>(
- value_for<n::string_id>("pretend:" + stringify(resolution()->resolvent()))
+ value_for<n::string_id>("usable_group:" + join(_imp->ids->begin(), _imp->ids->end(), "+", &stringify_job_id))
);
}
void
-PretendJob::serialise(Serialiser & s) const
+UsableGroupJob::serialise(Serialiser & s) const
{
- s.object("PretendJob")
+ s.object("UsableGroupJob")
.member(SerialiserFlags<serialise::might_be_null, serialise::container>(), "arrows", arrows())
- .member(SerialiserFlags<serialise::might_be_null>(), "decision", decision())
- .member(SerialiserFlags<serialise::might_be_null>(), "resolution", resolution())
+ .member(SerialiserFlags<serialise::might_be_null, serialise::container>(), "job_ids", job_ids())
+ .member(SerialiserFlags<serialise::container, serialise::might_be_null>(),
+ "used_existing_packages_when_ordering", used_existing_packages_when_ordering())
;
}
@@ -305,12 +353,30 @@ FetchJob::decision() const
return _imp->decision;
}
-const std::tr1::shared_ptr<ArrowSequence>
+const std::tr1::shared_ptr<const ArrowSequence>
FetchJob::arrows() const
{
return _imp->arrows;
}
+const std::tr1::shared_ptr<ArrowSequence>
+FetchJob::arrows()
+{
+ return _imp->arrows;
+}
+
+const std::tr1::shared_ptr<const JobIDSequence>
+FetchJob::used_existing_packages_when_ordering() const
+{
+ return _imp->used_existing_packages_when_ordering;
+}
+
+const std::tr1::shared_ptr<JobIDSequence>
+FetchJob::used_existing_packages_when_ordering()
+{
+ return _imp->used_existing_packages_when_ordering;
+}
+
const JobID
FetchJob::id() const
{
@@ -326,6 +392,8 @@ FetchJob::serialise(Serialiser & s) const
.member(SerialiserFlags<serialise::might_be_null, serialise::container>(), "arrows", arrows())
.member(SerialiserFlags<serialise::might_be_null>(), "decision", decision())
.member(SerialiserFlags<serialise::might_be_null>(), "resolution", resolution())
+ .member(SerialiserFlags<serialise::container, serialise::might_be_null>(),
+ "used_existing_packages_when_ordering", used_existing_packages_when_ordering())
;
}
@@ -351,12 +419,30 @@ SimpleInstallJob::decision() const
return _imp->decision;
}
-const std::tr1::shared_ptr<ArrowSequence>
+const std::tr1::shared_ptr<const ArrowSequence>
SimpleInstallJob::arrows() const
{
return _imp->arrows;
}
+const std::tr1::shared_ptr<ArrowSequence>
+SimpleInstallJob::arrows()
+{
+ return _imp->arrows;
+}
+
+const std::tr1::shared_ptr<const JobIDSequence>
+SimpleInstallJob::used_existing_packages_when_ordering() const
+{
+ return _imp->used_existing_packages_when_ordering;
+}
+
+const std::tr1::shared_ptr<JobIDSequence>
+SimpleInstallJob::used_existing_packages_when_ordering()
+{
+ return _imp->used_existing_packages_when_ordering;
+}
+
const JobID
SimpleInstallJob::id() const
{
@@ -372,89 +458,78 @@ SimpleInstallJob::serialise(Serialiser & s) const
.member(SerialiserFlags<serialise::might_be_null, serialise::container>(), "arrows", arrows())
.member(SerialiserFlags<serialise::might_be_null>(), "decision", decision())
.member(SerialiserFlags<serialise::might_be_null>(), "resolution", resolution())
+ .member(SerialiserFlags<serialise::container, serialise::might_be_null>(),
+ "used_existing_packages_when_ordering", used_existing_packages_when_ordering())
;
}
-UntakenInstallJob::UntakenInstallJob(const std::tr1::shared_ptr<const Resolution> & r) :
- PrivateImplementationPattern<UntakenInstallJob>(new Implementation<UntakenInstallJob>(r))
+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))
{
}
-UntakenInstallJob::~UntakenInstallJob()
+ErrorJob::~ErrorJob()
{
}
const std::tr1::shared_ptr<const Resolution>
-UntakenInstallJob::resolution() const
+ErrorJob::resolution() const
{
return _imp->resolution;
}
-const std::tr1::shared_ptr<ArrowSequence>
-UntakenInstallJob::arrows() const
+const std::tr1::shared_ptr<const ArrowSequence>
+ErrorJob::arrows() const
{
return _imp->arrows;
}
-const JobID
-UntakenInstallJob::id() const
-{
- return make_named_values<JobID>(
- value_for<n::string_id>("untaken:" + stringify(resolution()->resolvent()))
- );
-}
-
-void
-UntakenInstallJob::serialise(Serialiser & s) const
-{
- s.object("UntakenInstallJob")
- .member(SerialiserFlags<serialise::might_be_null, serialise::container>(), "arrows", arrows())
- .member(SerialiserFlags<serialise::might_be_null>(), "resolution", resolution())
- ;
-}
-
-SyncPointJob::SyncPointJob(const SyncPoint s) :
- PrivateImplementationPattern<SyncPointJob>(new Implementation<SyncPointJob>(s))
+const std::tr1::shared_ptr<ArrowSequence>
+ErrorJob::arrows()
{
+ return _imp->arrows;
}
-SyncPointJob::~SyncPointJob()
+const std::tr1::shared_ptr<const JobIDSequence>
+ErrorJob::used_existing_packages_when_ordering() const
{
+ return _imp->used_existing_packages_when_ordering;
}
-SyncPoint
-SyncPointJob::sync_point() const
+const std::tr1::shared_ptr<JobIDSequence>
+ErrorJob::used_existing_packages_when_ordering()
{
- return _imp->sync_point;
-}
-
-const std::tr1::shared_ptr<ArrowSequence>
-SyncPointJob::arrows() const
-{
- return _imp->arrows;
+ return _imp->used_existing_packages_when_ordering;
}
const JobID
-SyncPointJob::id() const
+ErrorJob::id() const
{
return make_named_values<JobID>(
- value_for<n::string_id>("sync:" + stringify(sync_point()))
+ value_for<n::string_id>("error:" + stringify(resolution()->resolvent()))
);
}
void
-SyncPointJob::serialise(Serialiser & s) const
+ErrorJob::serialise(Serialiser & s) const
{
- s.object("SyncPointJob")
+ s.object("ErrorJob")
.member(SerialiserFlags<serialise::might_be_null, serialise::container>(), "arrows", arrows())
- .member(SerialiserFlags<>(), "sync_point", stringify(sync_point()))
+ .member(SerialiserFlags<serialise::might_be_null>(), "decision", decision())
+ .member(SerialiserFlags<serialise::might_be_null>(), "resolution", resolution())
+ .member(SerialiserFlags<serialise::container, serialise::might_be_null>(),
+ "used_existing_packages_when_ordering", used_existing_packages_when_ordering())
;
}
+const std::tr1::shared_ptr<const UnableToMakeDecision>
+ErrorJob::decision() const
+{
+ return _imp->decision;
+}
template class PrivateImplementationPattern<resolver::UsableJob>;
-template class PrivateImplementationPattern<resolver::PretendJob>;
+template class PrivateImplementationPattern<resolver::UsableGroupJob>;
template class PrivateImplementationPattern<resolver::FetchJob>;
template class PrivateImplementationPattern<resolver::SimpleInstallJob>;
-template class PrivateImplementationPattern<resolver::SyncPointJob>;
-template class PrivateImplementationPattern<resolver::UntakenInstallJob>;
+template class PrivateImplementationPattern<resolver::ErrorJob>;
diff --git a/paludis/resolver/job.hh b/paludis/resolver/job.hh
index a007ef7..a227ddc 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 Ciaran McCreesh
+ * 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
@@ -39,7 +39,7 @@ namespace paludis
{
class PALUDIS_VISIBLE Job :
public virtual DeclareAbstractAcceptMethods<Job, MakeTypeList<
- UsableJob, SimpleInstallJob, PretendJob, FetchJob, UntakenInstallJob, SyncPointJob>::Type>
+ UsableJob, UsableGroupJob, SimpleInstallJob, FetchJob, ErrorJob>::Type>
{
public:
virtual ~Job() = 0;
@@ -47,9 +47,18 @@ namespace paludis
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 void serialise(Serialiser &) const = 0;
static const std::tr1::shared_ptr<Job> deserialise(
@@ -67,32 +76,47 @@ namespace paludis
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));
+
const std::tr1::shared_ptr<const Resolution> resolution() const PALUDIS_ATTRIBUTE((warn_unused_result));
virtual void serialise(Serialiser &) const;
};
- class PALUDIS_VISIBLE PretendJob :
+ class PALUDIS_VISIBLE UsableGroupJob :
public Job,
- public ImplementAcceptMethods<Job, PretendJob>,
- private PrivateImplementationPattern<PretendJob>
+ public ImplementAcceptMethods<Job, UsableGroupJob>,
+ private PrivateImplementationPattern<UsableGroupJob>
{
public:
- PretendJob(
- const std::tr1::shared_ptr<const Resolution> &,
- const std::tr1::shared_ptr<const ChangesToMakeDecision> &);
- ~PretendJob();
+ UsableGroupJob(const std::tr1::shared_ptr<const JobIDSequence> &);
+ ~UsableGroupJob();
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));
- const std::tr1::shared_ptr<const Resolution> resolution() const PALUDIS_ATTRIBUTE((warn_unused_result));
- const std::tr1::shared_ptr<const ChangesToMakeDecision> decision() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ virtual const std::tr1::shared_ptr<JobIDSequence> used_existing_packages_when_ordering()
+ 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;
};
@@ -110,9 +134,18 @@ namespace paludis
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));
+
const std::tr1::shared_ptr<const Resolution> resolution() const PALUDIS_ATTRIBUTE((warn_unused_result));
const std::tr1::shared_ptr<const ChangesToMakeDecision> decision() const PALUDIS_ATTRIBUTE((warn_unused_result));
@@ -132,49 +165,51 @@ namespace paludis
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));
+
const std::tr1::shared_ptr<const Resolution> resolution() const PALUDIS_ATTRIBUTE((warn_unused_result));
const std::tr1::shared_ptr<const ChangesToMakeDecision> decision() const PALUDIS_ATTRIBUTE((warn_unused_result));
virtual void serialise(Serialiser &) const;
};
- class PALUDIS_VISIBLE SyncPointJob :
+ class PALUDIS_VISIBLE ErrorJob :
public Job,
- public ImplementAcceptMethods<Job, SyncPointJob>,
- private PrivateImplementationPattern<SyncPointJob>
+ public ImplementAcceptMethods<Job, ErrorJob>,
+ private PrivateImplementationPattern<ErrorJob>
{
public:
- SyncPointJob(const SyncPoint);
- ~SyncPointJob();
+ 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<ArrowSequence> arrows()
+ virtual const std::tr1::shared_ptr<const ArrowSequence> arrows()
const PALUDIS_ATTRIBUTE((warn_unused_result));
- SyncPoint sync_point() const PALUDIS_ATTRIBUTE((warn_unused_result));
-
- virtual void serialise(Serialiser &) const;
- };
-
- class PALUDIS_VISIBLE UntakenInstallJob :
- public Job,
- public ImplementAcceptMethods<Job, UntakenInstallJob>,
- private PrivateImplementationPattern<UntakenInstallJob>
- {
- public:
- UntakenInstallJob(const std::tr1::shared_ptr<const Resolution> &);
- ~UntakenInstallJob();
-
- virtual const JobID id() 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));
+
const std::tr1::shared_ptr<const Resolution> resolution() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ const std::tr1::shared_ptr<const UnableToMakeDecision> decision() const PALUDIS_ATTRIBUTE((warn_unused_result));
virtual void serialise(Serialiser &) const;
};
@@ -182,11 +217,10 @@ namespace paludis
#ifdef PALUDIS_HAVE_EXTERN_TEMPLATE
extern template class PrivateImplementationPattern<resolver::UsableJob>;
- extern template class PrivateImplementationPattern<resolver::PretendJob>;
+ extern template class PrivateImplementationPattern<resolver::UsableGroupJob>;
extern template class PrivateImplementationPattern<resolver::FetchJob>;
extern template class PrivateImplementationPattern<resolver::SimpleInstallJob>;
- extern template class PrivateImplementationPattern<resolver::SyncPointJob>;
- extern template class PrivateImplementationPattern<resolver::UntakenInstallJob>;
+ extern template class PrivateImplementationPattern<resolver::ErrorJob>;
#endif
}
diff --git a/paludis/resolver/job_id.cc b/paludis/resolver/job_id.cc
index adba996..a8d5774 100644
--- a/paludis/resolver/job_id.cc
+++ b/paludis/resolver/job_id.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009 Ciaran McCreesh
+ * 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
@@ -39,6 +39,12 @@ 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
{
diff --git a/paludis/resolver/job_id.hh b/paludis/resolver/job_id.hh
index e93c9de..fc63947 100644
--- a/paludis/resolver/job_id.hh
+++ b/paludis/resolver/job_id.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009 Ciaran McCreesh
+ * 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
@@ -39,6 +39,7 @@ namespace paludis
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));
void serialise(Serialiser &) const;
static const JobID deserialise(Deserialisation & d) PALUDIS_ATTRIBUTE((warn_unused_result));
diff --git a/paludis/resolver/job_state-fwd.hh b/paludis/resolver/job_state-fwd.hh
new file mode 100644
index 0000000..fab624e
--- /dev/null
+++ b/paludis/resolver/job_state-fwd.hh
@@ -0,0 +1,35 @@
+/* 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_STATE_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_RESOLVER_JOB_STATE_FWD_HH 1
+
+namespace paludis
+{
+ namespace resolver
+ {
+ struct JobState;
+ struct JobPendingState;
+ struct JobSucceededState;
+ struct JobFailedState;
+ struct JobSkippedState;
+ }
+}
+
+#endif
diff --git a/paludis/resolver/job_state.cc b/paludis/resolver/job_state.cc
new file mode 100644
index 0000000..60afc2c
--- /dev/null
+++ b/paludis/resolver/job_state.cc
@@ -0,0 +1,180 @@
+/* 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_state.hh>
+#include <paludis/util/private_implementation_pattern-impl.hh>
+#include <list>
+
+using namespace paludis;
+using namespace paludis::resolver;
+
+JobState::~JobState()
+{
+}
+
+namespace paludis
+{
+ template <>
+ struct Implementation<JobPendingState>
+ {
+ const std::tr1::shared_ptr<const Job> job;
+
+ Implementation(const std::tr1::shared_ptr<const Job> & j) :
+ job(j)
+ {
+ }
+ };
+
+ template <>
+ struct Implementation<JobSucceededState>
+ {
+ const std::tr1::shared_ptr<const Job> job;
+ std::list<std::tr1::shared_ptr<OutputManager> > output_managers;
+
+ Implementation(const std::tr1::shared_ptr<const Job> & j) :
+ job(j)
+ {
+ }
+ };
+
+ template <>
+ struct Implementation<JobFailedState>
+ {
+ const std::tr1::shared_ptr<const Job> job;
+ std::list<std::tr1::shared_ptr<OutputManager> > output_managers;
+
+ Implementation(const std::tr1::shared_ptr<const Job> & j) :
+ job(j)
+ {
+ }
+ };
+
+ 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()
+{
+}
+
+const std::tr1::shared_ptr<const Job>
+JobSucceededState::job() const
+{
+ return _imp->job;
+}
+
+const std::string
+JobSucceededState::state_name() const
+{
+ return "succeeded";
+}
+
+void
+JobSucceededState::add_output_manager(const std::tr1::shared_ptr<OutputManager> & o)
+{
+ _imp->output_managers.push_back(o);
+}
+
+JobFailedState::JobFailedState(const std::tr1::shared_ptr<const Job> & j) :
+ PrivateImplementationPattern<JobFailedState>(new Implementation<JobFailedState>(j))
+{
+}
+
+JobFailedState::~JobFailedState()
+{
+}
+
+const std::tr1::shared_ptr<const Job>
+JobFailedState::job() const
+{
+ return _imp->job;
+}
+
+void
+JobFailedState::add_output_manager(const std::tr1::shared_ptr<OutputManager> & o)
+{
+ _imp->output_managers.push_back(o);
+}
+
+const std::string
+JobFailedState::state_name() const
+{
+ return "failed";
+}
+
+JobSkippedState::JobSkippedState(const std::tr1::shared_ptr<const Job> & j) :
+ PrivateImplementationPattern<JobSkippedState>(new Implementation<JobSkippedState>(j))
+{
+}
+
+JobSkippedState::~JobSkippedState()
+{
+}
+
+const std::tr1::shared_ptr<const Job>
+JobSkippedState::job() const
+{
+ return _imp->job;
+}
+
+const std::string
+JobSkippedState::state_name() const
+{
+ return "skipped";
+}
+
+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
new file mode 100644
index 0000000..1479e76
--- /dev/null
+++ b/paludis/resolver/job_state.hh
@@ -0,0 +1,114 @@
+/* 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_STATE_HH
+#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/output_manager-fwd.hh>
+#include <tr1/memory>
+#include <string>
+
+namespace paludis
+{
+ namespace resolver
+ {
+ class PALUDIS_VISIBLE JobState :
+ public virtual DeclareAbstractAcceptMethods<JobState, MakeTypeList<
+ JobPendingState, 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:
+ JobPendingState(const std::tr1::shared_ptr<const Job> &);
+ ~JobPendingState();
+
+ 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));
+ };
+
+ class PALUDIS_VISIBLE JobSucceededState :
+ public JobState,
+ public ImplementAcceptMethods<JobState, JobSucceededState>,
+ private PrivateImplementationPattern<JobSucceededState>
+ {
+ public:
+ JobSucceededState(const std::tr1::shared_ptr<const Job> &);
+ ~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> &);
+ };
+
+ class PALUDIS_VISIBLE JobFailedState :
+ public JobState,
+ public ImplementAcceptMethods<JobState, JobFailedState>,
+ private PrivateImplementationPattern<JobFailedState>
+ {
+ public:
+ JobFailedState(const std::tr1::shared_ptr<const Job> &);
+ ~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> &);
+ };
+
+ class PALUDIS_VISIBLE JobSkippedState :
+ public JobState,
+ public ImplementAcceptMethods<JobState, JobSkippedState>,
+ private PrivateImplementationPattern<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
index fd29956..965466e 100644
--- a/paludis/resolver/jobs.cc
+++ b/paludis/resolver/jobs.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009 Ciaran McCreesh
+ * 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
@@ -25,6 +25,7 @@
#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>
@@ -75,17 +76,16 @@ namespace
jobs_list_by_resolvent_index.insert(std::make_pair(j.resolution()->resolvent(), i));
}
- void visit(const SimpleInstallJob & j)
+ void visit(const UsableGroupJob &)
{
- jobs_list_by_resolvent_index.insert(std::make_pair(j.resolution()->resolvent(), i));
}
- void visit(const UntakenInstallJob & j)
+ void visit(const SimpleInstallJob & j)
{
jobs_list_by_resolvent_index.insert(std::make_pair(j.resolution()->resolvent(), i));
}
- void visit(const PretendJob & j)
+ void visit(const ErrorJob & j)
{
jobs_list_by_resolvent_index.insert(std::make_pair(j.resolution()->resolvent(), i));
}
@@ -94,10 +94,6 @@ namespace
{
jobs_list_by_resolvent_index.insert(std::make_pair(j.resolution()->resolvent(), i));
}
-
- void visit(const SyncPointJob &)
- {
- }
};
}
@@ -114,27 +110,22 @@ namespace
{
struct InstalledJobChecker
{
- bool visit(const PretendJob &) const
+ bool visit(const FetchJob &) const
{
return false;
}
- bool visit(const SyncPointJob &) const
+ bool visit(const ErrorJob &) const
{
- return false;
+ return true;
}
- bool visit(const FetchJob &) const
+ bool visit(const UsableJob &) const
{
return false;
}
- bool visit(const UntakenInstallJob &) const
- {
- return true;
- }
-
- bool visit(const UsableJob &) const
+ bool visit(const UsableGroupJob &) const
{
return false;
}
@@ -147,26 +138,21 @@ namespace
struct UsableJobChecker
{
- bool visit(const PretendJob &) const
+ bool visit(const FetchJob &) const
{
return false;
}
- bool visit(const SyncPointJob &) const
+ bool visit(const ErrorJob &) const
{
- return false;
+ return true;
}
- bool visit(const FetchJob &) const
+ bool visit(const UsableGroupJob &) const
{
return false;
}
- bool visit(const UntakenInstallJob &) const
- {
- return true;
- }
-
bool visit(const UsableJob &) const
{
return true;
@@ -251,12 +237,23 @@ Jobs::fetch(const JobID & id)
const std::tr1::shared_ptr<const Job>
Jobs::fetch(const JobID & id) const
{
- for (JobsList::const_iterator j(_imp->jobs.begin()), j_end(_imp->jobs.end()) ;
- j != j_end ; ++j)
- if ((*j)->id() == id)
- return *j;
+ 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;
+}
- throw InternalError(PALUDIS_HERE, "no job for id");
+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
@@ -280,3 +277,8 @@ Jobs::deserialise(Deserialisation & d)
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
index d49a349..bdd9dfa 100644
--- a/paludis/resolver/jobs.hh
+++ b/paludis/resolver/jobs.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009 Ciaran McCreesh
+ * 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
@@ -56,6 +56,10 @@ namespace paludis
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(
diff --git a/paludis/resolver/orderer.cc b/paludis/resolver/orderer.cc
index 4aea541..a51411a 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 Ciaran McCreesh
+ * 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
@@ -41,7 +41,6 @@
#include <paludis/util/private_implementation_pattern-impl.hh>
#include <paludis/util/log.hh>
#include <paludis/util/simple_visitor_cast.hh>
-#include <paludis/util/hashes.hh>
#include <paludis/match_package.hh>
#include <paludis/generator.hh>
#include <paludis/filter.hh>
@@ -49,11 +48,13 @@
#include <paludis/selection.hh>
#include <paludis/notifier_callback.hh>
#include <algorithm>
-#include <tr1/unordered_set>
+#include <set>
using namespace paludis;
using namespace paludis::resolver;
+typedef std::set<JobID> ToOrder;
+
namespace paludis
{
template <>
@@ -64,7 +65,7 @@ namespace paludis
const std::tr1::shared_ptr<ResolverLists> lists;
- std::tr1::unordered_set<JobID, Hash<JobID> > already_ordered;
+ ToOrder to_order;
Implementation(const Environment * const e,
const std::tr1::shared_ptr<const Decider> & d,
@@ -109,25 +110,19 @@ namespace paludis
namespace
{
- struct CommonJobs
- {
- NamedValue<n::done_installs, std::tr1::shared_ptr<Job> > done_installs;
- NamedValue<n::done_pretends, std::tr1::shared_ptr<Job> > done_pretends;
- };
-
struct DecisionHandler
{
- CommonJobs & common_jobs;
const std::tr1::shared_ptr<Resolution> resolution;
const std::tr1::shared_ptr<ResolverLists> lists;
+ ToOrder & to_order;
DecisionHandler(
- CommonJobs & c,
const std::tr1::shared_ptr<Resolution> & r,
- const std::tr1::shared_ptr<ResolverLists> & l) :
- common_jobs(c),
+ const std::tr1::shared_ptr<ResolverLists> & l,
+ ToOrder & o) :
resolution(r),
- lists(l)
+ lists(l),
+ to_order(o)
{
}
@@ -140,15 +135,7 @@ namespace
const std::tr1::shared_ptr<UsableJob> usable_job(new UsableJob(resolution));
lists->jobs()->add(usable_job);
- lists->unordered_job_ids()->push_back(usable_job->id());
-
- /* we want to do all of these as part of the main build process,
- * not at pretend time */
- usable_job->arrows()->push_back(make_named_values<Arrow>(
- value_for<n::comes_after>(common_jobs.done_pretends()->id()),
- value_for<n::failure_kinds>(FailureKinds()),
- value_for<n::maybe_reason>(make_null_shared_ptr())
- ));
+ to_order.insert(usable_job->id());
}
else
{
@@ -166,15 +153,7 @@ namespace
const std::tr1::shared_ptr<UsableJob> usable_job(new UsableJob(resolution));
lists->jobs()->add(usable_job);
- lists->unordered_job_ids()->push_back(usable_job->id());
-
- /* we want to do all of these as part of the main build process,
- * not at pretend time */
- usable_job->arrows()->push_back(make_named_values<Arrow>(
- value_for<n::comes_after>(common_jobs.done_pretends()->id()),
- value_for<n::failure_kinds>(FailureKinds()),
- value_for<n::maybe_reason>(make_null_shared_ptr())
- ));
+ to_order.insert(usable_job->id());
}
else
{
@@ -190,53 +169,19 @@ namespace
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<PretendJob> pretend_job(new PretendJob(resolution,
- d.shared_from_this()));
- lists->jobs()->add(pretend_job);
- lists->unordered_job_ids()->push_back(pretend_job->id());
-
const std::tr1::shared_ptr<FetchJob> fetch_job(new FetchJob(resolution,
d.shared_from_this()));
lists->jobs()->add(fetch_job);
- lists->unordered_job_ids()->push_back(fetch_job->id());
+ 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);
- lists->unordered_job_ids()->push_back(install_job->id());
+ to_order.insert(install_job->id());
const std::tr1::shared_ptr<UsableJob> usable_job(new UsableJob(resolution));
lists->jobs()->add(usable_job);
- lists->unordered_job_ids()->push_back(usable_job->id());
-
- /* we can't do any fetches or installs until all pretends have passed */
- fetch_job->arrows()->push_back(make_named_values<Arrow>(
- value_for<n::comes_after>(common_jobs.done_pretends()->id()),
- value_for<n::failure_kinds>(FailureKinds()),
- value_for<n::maybe_reason>(make_null_shared_ptr())
- ));
-
- install_job->arrows()->push_back(make_named_values<Arrow>(
- value_for<n::comes_after>(common_jobs.done_pretends()->id()),
- value_for<n::failure_kinds>(FailureKinds()),
- value_for<n::maybe_reason>(make_null_shared_ptr())
- ));
-
- /* we haven't done all our pretends until we've done our pretend */
- common_jobs.done_pretends()->arrows()->push_back(make_named_values<Arrow>(
- value_for<n::comes_after>(pretend_job->id()),
- value_for<n::failure_kinds>(FailureKinds()),
- value_for<n::maybe_reason>(make_null_shared_ptr())
- ));
-
- /* we haven't done all our installs until we're usable
- * (arguably this should just be install rather than usable,
- * but the stronger requirement doesn't seem to hurt */
- common_jobs.done_installs()->arrows()->push_back(make_named_values<Arrow>(
- value_for<n::comes_after>(usable_job->id()),
- value_for<n::failure_kinds>(FailureKinds()),
- value_for<n::maybe_reason>(make_null_shared_ptr())
- ));
+ to_order.insert(usable_job->id());
/* we can't install until we've fetched */
install_job->arrows()->push_back(make_named_values<Arrow>(
@@ -257,7 +202,7 @@ namespace
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<UntakenInstallJob> install_job(new UntakenInstallJob(resolution));
+ 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());
}
@@ -270,16 +215,18 @@ namespace
Log::get_instance()->message("resolver.orderer.job.unable_to_make", ll_debug, lc_no_context)
<< "taken " << resolution->resolvent() << " unable to make";
- lists->error_resolutions()->append(resolution);
+ 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());
}
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<UntakenInstallJob> install_job(new UntakenInstallJob(resolution));
- lists->jobs()->add(install_job);
- lists->untaken_job_ids()->push_back(install_job->id());
+ 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());
}
}
};
@@ -288,22 +235,11 @@ namespace
void
Orderer::_resolve_jobs()
{
- CommonJobs common_jobs(make_named_values<CommonJobs>(
- value_for<n::done_installs>(make_shared_ptr(new SyncPointJob(sp_done_installs))),
- value_for<n::done_pretends>(make_shared_ptr(new SyncPointJob(sp_done_pretends)))
- ));
-
- _imp->lists->jobs()->add(common_jobs.done_installs());
- _imp->lists->unordered_job_ids()->push_back(common_jobs.done_installs()->id());
-
- _imp->lists->jobs()->add(common_jobs.done_pretends());
- _imp->lists->unordered_job_ids()->push_back(common_jobs.done_pretends()->id());
-
for (Resolutions::ConstIterator i(_imp->lists->all_resolutions()->begin()),
i_end(_imp->lists->all_resolutions()->end()) ;
i != i_end ; ++i)
{
- DecisionHandler d(common_jobs, *i, _imp->lists);
+ DecisionHandler d(*i, _imp->lists, _imp->to_order);
(*i)->decision()->accept(d);
}
}
@@ -512,19 +448,15 @@ namespace
add_dep_arrows(true, c.resolution());
}
- void visit(const FetchJob &)
+ void visit(const UsableGroupJob &)
{
}
- void visit(const PretendJob &)
- {
- }
-
- void visit(const UntakenInstallJob &)
+ void visit(const FetchJob &)
{
}
- void visit(const SyncPointJob &)
+ void visit(const ErrorJob &)
{
}
};
@@ -535,8 +467,8 @@ Orderer::_resolve_jobs_dep_arrows()
{
Context context("When resolving dep arrows:");
- for (JobIDSequence::ConstIterator i(_imp->lists->unordered_job_ids()->begin()),
- i_end(_imp->lists->unordered_job_ids()->end()) ;
+ for (ToOrder::const_iterator i(_imp->to_order.begin()),
+ i_end(_imp->to_order.end()) ;
i != i_end ; ++i)
{
DepArrowHandler d(_imp->lists->jobs(), *i);
@@ -552,7 +484,7 @@ Orderer::_resolve_order()
_imp->env->trigger_notifier_callback(NotifierCallbackResolverStageEvent("Ordering"));
/* anything left? */
- if (! _anything_left_to_order())
+ if (_imp->to_order.empty())
break;
/* first attempt: nothing fancy */
@@ -581,32 +513,16 @@ Orderer::_resolve_order()
}
bool
-Orderer::_anything_left_to_order() const
-{
- for (JobIDSequence::ConstIterator i(_imp->lists->unordered_job_ids()->begin()),
- i_end(_imp->lists->unordered_job_ids()->end()) ;
- i != i_end ; ++i)
- {
- if (_already_ordered(*i))
- continue;
-
- return true;
- }
-
- return false;
-}
-
-bool
Orderer::_order_some(const bool desperate, const bool installs_only)
{
bool result(false);
- for (JobIDSequence::ConstIterator i(_imp->lists->unordered_job_ids()->begin()),
- i_end(_imp->lists->unordered_job_ids()->end()) ;
- i != i_end ; ++i)
+ for (ToOrder::iterator i(_imp->to_order.begin()), i_next(i), i_end(_imp->to_order.end()) ;
+ i != i_end ; i = i_next)
{
- if (_already_ordered(*i))
- continue;
+ /* i might end up invalidated by the time we're done */
+ JobID id(*i);
+ ++i_next;
if (installs_only)
{
@@ -615,46 +531,42 @@ Orderer::_order_some(const bool desperate, const bool installs_only)
continue;
}
- if (! _can_order(*i, desperate))
+ if (! _can_order(id, desperate))
continue;
if (desperate)
{
- const std::tr1::shared_ptr<const Job> job(_imp->lists->jobs()->fetch(*i));
- std::stringstream s;
+ 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 (! _already_ordered(a->comes_after()))
- {
- if (! s.str().empty())
- s << ", ";
- s << a->comes_after().string_id();
- }
-
- Log::get_instance()->message("resolver.orderer.cycle_breaking.already_met", ll_warning, lc_context)
- << "Had to use existing packages to order " << i->string_id() << " (unmet deps are " << s.str() << ")";
+ if (_imp->to_order.end() != _imp->to_order.find(a->comes_after()))
+ job->used_existing_packages_when_ordering()->push_back(a->comes_after());
}
- _imp->lists->ordered_job_ids()->push_back(*i);
- _mark_already_ordered(*i);
+ _order_this(id, false);
result = true;
}
return result;
}
+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);
+}
+
bool
Orderer::_remove_usable_cycles()
{
/* we only want to remove usable jobs... */
- std::tr1::unordered_set<JobID, Hash<JobID> > removable;
- for (JobIDSequence::ConstIterator i(_imp->lists->unordered_job_ids()->begin()),
- i_end(_imp->lists->unordered_job_ids()->end()) ;
+ std::set<JobID> removable;
+ for (ToOrder::const_iterator i(_imp->to_order.begin()),
+ i_end(_imp->to_order.end()) ;
i != i_end ; ++i)
{
- if (_already_ordered(*i))
- continue;
-
const std::tr1::shared_ptr<const Job> job(_imp->lists->jobs()->fetch(*i));
if (simple_visitor_cast<const UsableJob>(*job))
removable.insert(job->id());
@@ -674,7 +586,7 @@ Orderer::_remove_usable_cycles()
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 (! _already_ordered(a->comes_after()))
+ if (_imp->to_order.end() != _imp->to_order.find(a->comes_after()))
if (removable.end() == removable.find(a->comes_after()))
{
need_another_pass = true;
@@ -690,12 +602,22 @@ Orderer::_remove_usable_cycles()
break;
}
- for (std::tr1::unordered_set<JobID, Hash<JobID> >::iterator i(removable.begin()),
- i_end(removable.end()) ;
- i != i_end ; ++i)
+ if (! removable.empty())
{
- _imp->lists->ordered_job_ids()->push_back(*i);
- _mark_already_ordered(*i);
+ const std::tr1::shared_ptr<JobIDSequence> ids(new JobIDSequence);
+ std::copy(removable.begin(), removable.end(), ids->back_inserter());
+
+ 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);
+
+ 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);
+ }
}
return ! removable.empty();
@@ -705,18 +627,15 @@ void
Orderer::_cycle_error()
{
std::stringstream s;
- for (JobIDSequence::ConstIterator i(_imp->lists->unordered_job_ids()->begin()),
- i_end(_imp->lists->unordered_job_ids()->end()) ;
+ for (ToOrder::const_iterator i(_imp->to_order.begin()),
+ i_end(_imp->to_order.end()) ;
i != i_end ; ++i)
{
- if (_already_ordered(*i))
- continue;
-
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 (! _already_ordered(a->comes_after()))
+ if (_imp->to_order.end() != _imp->to_order.find(a->comes_after()))
s << " [" << a->comes_after().string_id() << "]";
s << " }}}";
}
@@ -759,7 +678,7 @@ Orderer::_can_order(const JobID & i, const bool desperate) const
for (ArrowSequence::ConstIterator a(job->arrows()->begin()), a_end(job->arrows()->end()) ;
a != a_end ; ++a)
{
- if (! _already_ordered(a->comes_after()))
+ if (_imp->to_order.end() != _imp->to_order.find(a->comes_after()))
{
bool skippable(false);
@@ -779,18 +698,10 @@ Orderer::_can_order(const JobID & i, const bool desperate) const
return true;
}
-bool
-Orderer::_already_ordered(const JobID & i) const
-{
- return _imp->already_ordered.end() != _imp->already_ordered.find(i);
-}
-
void
Orderer::_mark_already_ordered(const JobID & i)
{
- if (! _imp->already_ordered.insert(i).second)
- throw InternalError(PALUDIS_HERE, "already already ordered");
-
+ _imp->to_order.erase(i);
_imp->env->trigger_notifier_callback(NotifierCallbackResolverStepEvent());
}
diff --git a/paludis/resolver/orderer.hh b/paludis/resolver/orderer.hh
index 313d19d..12523c6 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 Ciaran McCreesh
+ * 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
@@ -48,11 +48,10 @@ namespace paludis
void _resolve_jobs_dep_arrows();
void _resolve_order();
- bool _already_ordered(const JobID &) const PALUDIS_ATTRIBUTE((warn_unused_result));
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 _anything_left_to_order() const PALUDIS_ATTRIBUTE((warn_unused_result));
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));
diff --git a/paludis/resolver/resolver.cc b/paludis/resolver/resolver.cc
index 23034e9..4876cbb 100644
--- a/paludis/resolver/resolver.cc
+++ b/paludis/resolver/resolver.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009 Ciaran McCreesh
+ * 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
@@ -61,10 +61,10 @@ namespace paludis
fns(f),
lists(new ResolverLists(make_named_values<ResolverLists>(
value_for<n::all_resolutions>(make_shared_ptr(new Resolutions)),
- value_for<n::error_resolutions>(make_shared_ptr(new Resolutions)),
value_for<n::jobs>(make_shared_ptr(new Jobs)),
- value_for<n::ordered_job_ids>(make_shared_ptr(new JobIDSequence)),
- value_for<n::unordered_job_ids>(make_shared_ptr(new JobIDSequence)),
+ value_for<n::taken_error_job_ids>(make_shared_ptr(new JobIDSequence)),
+ value_for<n::taken_job_ids>(make_shared_ptr(new JobIDSequence)),
+ value_for<n::untaken_error_job_ids>(make_shared_ptr(new JobIDSequence)),
value_for<n::untaken_job_ids>(make_shared_ptr(new JobIDSequence))
))),
decider(new Decider(e, f, lists)),
diff --git a/paludis/resolver/resolver_TEST_any.cc b/paludis/resolver/resolver_TEST_any.cc
index 5b55b6f..18c8c28 100644
--- a/paludis/resolver/resolver_TEST_any.cc
+++ b/paludis/resolver/resolver_TEST_any.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009 Ciaran McCreesh
+ * Copyright (c) 2009, 2010 Ciaran McCreesh
* Copyright (c) 2009 David Leverton
*
* This file is part of the Paludis package manager. Paludis is free software;
@@ -76,15 +76,23 @@ namespace test_cases
std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("test/target"));
{
- TestMessageSuffix s("errors");
- check_resolution_list(resolutions->jobs(), resolutions->error_resolutions(), ResolutionListChecks()
+ 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->ordered_job_ids(), ResolutionListChecks()
+ check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
.qpn(QualifiedPackageName("test/target"))
.finished()
);
@@ -103,15 +111,22 @@ namespace test_cases
std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("test/target"));
{
- TestMessageSuffix s("errors");
- check_resolution_list(resolutions->jobs(), resolutions->error_resolutions(), ResolutionListChecks()
+ 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->ordered_job_ids(), ResolutionListChecks()
+ check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
.qpn(QualifiedPackageName("test/dep"))
.qpn(QualifiedPackageName("test/target"))
.finished()
@@ -131,15 +146,22 @@ namespace test_cases
std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("test/target"));
{
- TestMessageSuffix s("errors");
- check_resolution_list(resolutions->jobs(), resolutions->error_resolutions(), ResolutionListChecks()
+ 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->ordered_job_ids(), ResolutionListChecks()
+ check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
.qpn(QualifiedPackageName("test/target"))
.finished()
);
diff --git a/paludis/resolver/resolver_TEST_blockers.cc b/paludis/resolver/resolver_TEST_blockers.cc
index 28ab165..758618c 100644
--- a/paludis/resolver/resolver_TEST_blockers.cc
+++ b/paludis/resolver/resolver_TEST_blockers.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009 Ciaran McCreesh
+ * 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
@@ -78,15 +78,22 @@ namespace test_cases
std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("hard/target"));
{
- TestMessageSuffix s("errors");
- check_resolution_list(resolutions->jobs(), resolutions->error_resolutions(), ResolutionListChecks()
+ 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->ordered_job_ids(), ResolutionListChecks()
+ check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
.qpn(QualifiedPackageName("hard/a-pkg"))
.qpn(QualifiedPackageName("hard/z-pkg"))
.qpn(QualifiedPackageName("hard/target"))
diff --git a/paludis/resolver/resolver_TEST_cycles.cc b/paludis/resolver/resolver_TEST_cycles.cc
index ced07c8..71ba3eb 100644
--- a/paludis/resolver/resolver_TEST_cycles.cc
+++ b/paludis/resolver/resolver_TEST_cycles.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009 Ciaran McCreesh
+ * 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
@@ -95,15 +95,22 @@ namespace test_cases
std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("no-changes/target"));
{
- TestMessageSuffix s("errors");
- check_resolution_list(resolutions->jobs(), resolutions->error_resolutions(), ResolutionListChecks()
+ 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->ordered_job_ids(), ResolutionListChecks()
+ check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
.qpn(QualifiedPackageName("no-changes/target"))
.finished()
);
@@ -122,15 +129,22 @@ namespace test_cases
std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("existing-usable/target"));
{
- TestMessageSuffix s("errors");
- check_resolution_list(resolutions->jobs(), resolutions->error_resolutions(), ResolutionListChecks()
+ 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->ordered_job_ids(), ResolutionListChecks()
+ check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
.qpn(QualifiedPackageName("existing-usable/target"))
.qpn(QualifiedPackageName("existing-usable/dep"))
.finished()
@@ -148,15 +162,22 @@ namespace test_cases
std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("mutual-run-deps/target"));
{
- TestMessageSuffix s("errors");
- check_resolution_list(resolutions->jobs(), resolutions->error_resolutions(), ResolutionListChecks()
+ 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->ordered_job_ids(), ResolutionListChecks()
+ 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"))
diff --git a/paludis/resolver/resolver_TEST_serialisation.cc b/paludis/resolver/resolver_TEST_serialisation.cc
index 44cc273..be037b9 100644
--- a/paludis/resolver/resolver_TEST_serialisation.cc
+++ b/paludis/resolver/resolver_TEST_serialisation.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009 Ciaran McCreesh
+ * 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
@@ -89,16 +89,23 @@ namespace test_cases
}
{
- TestMessageSuffix s("errors");
- check_resolution_list(resolutions->jobs(), resolutions->error_resolutions(), ResolutionListChecks()
+ 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->ordered_job_ids(), ResolutionListChecks()
+ check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
.qpn(QualifiedPackageName("serialisation/dep"))
.qpn(QualifiedPackageName("serialisation/target"))
.finished()
diff --git a/paludis/resolver/resolver_TEST_simple.cc b/paludis/resolver/resolver_TEST_simple.cc
index 9e50b7e..81bfea0 100644
--- a/paludis/resolver/resolver_TEST_simple.cc
+++ b/paludis/resolver/resolver_TEST_simple.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009 Ciaran McCreesh
+ * 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
@@ -75,15 +75,23 @@ namespace test_cases
std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("no-deps/target"));
{
- TestMessageSuffix s("errors");
- check_resolution_list(resolutions->jobs(), resolutions->error_resolutions(), ResolutionListChecks()
+ 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->ordered_job_ids(), ResolutionListChecks()
+ check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
.qpn(QualifiedPackageName("no-deps/target"))
.finished()
);
@@ -100,15 +108,23 @@ namespace test_cases
std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("build-deps/target"));
{
- TestMessageSuffix s("errors");
- check_resolution_list(resolutions->jobs(), resolutions->error_resolutions(), ResolutionListChecks()
+ 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->ordered_job_ids(), ResolutionListChecks()
+ 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"))
diff --git a/paludis/resolver/resolver_TEST_suggestions.cc b/paludis/resolver/resolver_TEST_suggestions.cc
index 92080e6..7810b1f 100644
--- a/paludis/resolver/resolver_TEST_suggestions.cc
+++ b/paludis/resolver/resolver_TEST_suggestions.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009 Ciaran McCreesh
+ * 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
@@ -75,15 +75,23 @@ namespace test_cases
std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("suggestion/target"));
{
- TestMessageSuffix s("errors");
- check_resolution_list(resolutions->jobs(), resolutions->error_resolutions(), ResolutionListChecks()
+ 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->ordered_job_ids(), ResolutionListChecks()
+ check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
.qpn(QualifiedPackageName("suggestion/target"))
.finished()
);
@@ -108,15 +116,23 @@ namespace test_cases
std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("unmeetable-suggestion/target"));
{
- TestMessageSuffix s("errors");
- check_resolution_list(resolutions->jobs(), resolutions->error_resolutions(), ResolutionListChecks()
+ 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->ordered_job_ids(), ResolutionListChecks()
+ check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
.qpn(QualifiedPackageName("unmeetable-suggestion/target"))
.finished()
);
@@ -141,15 +157,23 @@ namespace test_cases
std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("suggestion-then-dependency/target"));
{
- TestMessageSuffix s("errors");
- check_resolution_list(resolutions->jobs(), resolutions->error_resolutions(), ResolutionListChecks()
+ 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->ordered_job_ids(), ResolutionListChecks()
+ 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"))
diff --git a/paludis/resolver/resolver_TEST_virtuals.cc b/paludis/resolver/resolver_TEST_virtuals.cc
index c2333fc..53385b4 100644
--- a/paludis/resolver/resolver_TEST_virtuals.cc
+++ b/paludis/resolver/resolver_TEST_virtuals.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009 Ciaran McCreesh
+ * 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
@@ -75,15 +75,22 @@ namespace test_cases
std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("virtuals/target"));
{
- TestMessageSuffix s("errors");
- check_resolution_list(resolutions->jobs(), resolutions->error_resolutions(), ResolutionListChecks()
+ 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->ordered_job_ids(), ResolutionListChecks()
+ check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
.qpn(QualifiedPackageName("cat/foo-a"))
.qpn(QualifiedPackageName("virtuals/target"))
.finished()
@@ -108,15 +115,22 @@ namespace test_cases
std::tr1::shared_ptr<const ResolverLists> resolutions(get_resolutions("virtual/virtual-target"));
{
- TestMessageSuffix s("errors");
- check_resolution_list(resolutions->jobs(), resolutions->error_resolutions(), ResolutionListChecks()
+ 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->ordered_job_ids(), ResolutionListChecks()
+ check_resolution_list(resolutions->jobs(), resolutions->taken_job_ids(), ResolutionListChecks()
.qpn(QualifiedPackageName("cat/real-target"))
.finished()
);
diff --git a/paludis/resolver/resolver_lists.cc b/paludis/resolver/resolver_lists.cc
index 40892ef..80f095d 100644
--- a/paludis/resolver/resolver_lists.cc
+++ b/paludis/resolver/resolver_lists.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009 Ciaran McCreesh
+ * 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
@@ -34,10 +34,10 @@ ResolverLists::serialise(Serialiser & s) const
{
s.object("ResolverLists")
.member(SerialiserFlags<serialise::might_be_null>(), "all_resolutions", all_resolutions())
- .member(SerialiserFlags<serialise::might_be_null>(), "error_resolutions", error_resolutions())
.member(SerialiserFlags<serialise::might_be_null>(), "jobs", jobs())
- .member(SerialiserFlags<serialise::container, serialise::might_be_null>(), "ordered_job_ids", ordered_job_ids())
- .member(SerialiserFlags<serialise::container, serialise::might_be_null>(), "unordered_job_ids", unordered_job_ids())
+ .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())
;
}
@@ -47,18 +47,25 @@ ResolverLists::deserialise(Deserialisation & d)
{
Deserialisator v(d, "ResolverLists");
- std::tr1::shared_ptr<JobIDSequence> ordered_job_ids(new JobIDSequence);
+ std::tr1::shared_ptr<JobIDSequence> taken_error_job_ids(new JobIDSequence);
{
- Deserialisator vv(*v.find_remove_member("ordered_job_ids"), "c");
+ 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)
- ordered_job_ids->push_back(vv.member<JobID>(stringify(n)));
+ taken_error_job_ids->push_back(vv.member<JobID>(stringify(n)));
}
- std::tr1::shared_ptr<JobIDSequence> unordered_job_ids(new JobIDSequence);
+ std::tr1::shared_ptr<JobIDSequence> taken_job_ids(new JobIDSequence);
{
- Deserialisator vv(*v.find_remove_member("unordered_job_ids"), "c");
+ 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)
- unordered_job_ids->push_back(vv.member<JobID>(stringify(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);
@@ -70,10 +77,10 @@ ResolverLists::deserialise(Deserialisation & d)
return make_named_values<ResolverLists>(
value_for<n::all_resolutions>(v.member<std::tr1::shared_ptr<Resolutions> >("all_resolutions")),
- value_for<n::error_resolutions>(v.member<std::tr1::shared_ptr<Resolutions> >("error_resolutions")),
value_for<n::jobs>(v.member<std::tr1::shared_ptr<Jobs> >("jobs")),
- value_for<n::ordered_job_ids>(ordered_job_ids),
- value_for<n::unordered_job_ids>(unordered_job_ids),
+ value_for<n::taken_error_job_ids>(taken_error_job_ids),
+ value_for<n::taken_job_ids>(taken_job_ids),
+ value_for<n::untaken_error_job_ids>(untaken_error_job_ids),
value_for<n::untaken_job_ids>(untaken_job_ids)
);
}
diff --git a/paludis/resolver/resolver_lists.hh b/paludis/resolver/resolver_lists.hh
index 184d6f5..4c704fc 100644
--- a/paludis/resolver/resolver_lists.hh
+++ b/paludis/resolver/resolver_lists.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009 Ciaran McCreesh
+ * 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
@@ -33,10 +33,10 @@ namespace paludis
namespace n
{
struct all_resolutions;
- struct error_resolutions;
struct jobs;
- struct ordered_job_ids;
- struct unordered_job_ids;
+ struct taken_error_job_ids;
+ struct taken_job_ids;
+ struct untaken_error_job_ids;
struct untaken_job_ids;
}
@@ -45,10 +45,10 @@ namespace paludis
struct ResolverLists
{
NamedValue<n::all_resolutions, std::tr1::shared_ptr<Resolutions> > all_resolutions;
- NamedValue<n::error_resolutions, std::tr1::shared_ptr<Resolutions> > error_resolutions;
NamedValue<n::jobs, std::tr1::shared_ptr<Jobs> > jobs;
- NamedValue<n::ordered_job_ids, std::tr1::shared_ptr<JobIDSequence> > ordered_job_ids;
- NamedValue<n::unordered_job_ids, std::tr1::shared_ptr<JobIDSequence> > unordered_job_ids;
+ 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));
diff --git a/paludis/resolver/resolver_test.cc b/paludis/resolver/resolver_test.cc
index de03107..72b45f5 100644
--- a/paludis/resolver/resolver_test.cc
+++ b/paludis/resolver/resolver_test.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009 Ciaran McCreesh
+ * 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
@@ -513,22 +513,17 @@ namespace
return make_null_shared_ptr();
}
- std::tr1::shared_ptr<const Resolution> visit(const FetchJob &) const
- {
- return make_null_shared_ptr();
- }
-
- std::tr1::shared_ptr<const Resolution> visit(const PretendJob &) const
+ std::tr1::shared_ptr<const Resolution> visit(const UsableGroupJob &) const
{
return make_null_shared_ptr();
}
- std::tr1::shared_ptr<const Resolution> visit(const SyncPointJob &) const
+ std::tr1::shared_ptr<const Resolution> visit(const FetchJob &) const
{
return make_null_shared_ptr();
}
- std::tr1::shared_ptr<const Resolution> visit(const UntakenInstallJob & j) const
+ std::tr1::shared_ptr<const Resolution> visit(const ErrorJob & j) const
{
return j.resolution();
}
diff --git a/src/clients/cave/cmd_display_resolution.cc b/src/clients/cave/cmd_display_resolution.cc
index cc1d8b0..a8c5dc3 100644
--- a/src/clients/cave/cmd_display_resolution.cc
+++ b/src/clients/cave/cmd_display_resolution.cc
@@ -210,26 +210,27 @@ namespace
}
}
- void display_one_constraint(const Constraint & c)
+ const std::string constraint_as_string(const Constraint & c)
{
- cout << c.spec();
+ std::stringstream result;
+ result << c.spec();
switch (c.use_existing())
{
case ue_if_same:
- cout << ", use existing if same";
+ result << ", use existing if same";
break;
case ue_never:
- cout << ", never using existing";
+ result << ", never using existing";
break;
case ue_only_if_transient:
- cout << ", using existing only if transient";
+ result << ", using existing only if transient";
break;
case ue_if_same_version:
- cout << ", use existing if same version";
+ result << ", use existing if same version";
break;
case ue_if_possible:
- cout << ", use existing if possible";
+ result << ", use existing if possible";
break;
case last_ue:
@@ -239,16 +240,18 @@ namespace
switch (c.destination_type())
{
case dt_install_to_slash:
- cout << ", installing to /";
+ result << ", installing to /";
break;
case dt_create_binary:
- cout << ", creating a binary";
+ result << ", creating a binary";
break;
case last_dt:
break;
}
+
+ return result.str();
}
void display_explanation_constraints(const Constraints & constraints)
@@ -257,9 +260,7 @@ namespace
for (Constraints::ConstIterator c(constraints.begin()), c_end(constraints.end()) ;
c != c_end ; ++c)
{
- cout << " * ";
- display_one_constraint(**c);
- cout << endl;
+ cout << " * " << constraint_as_string(**c) << endl;
cout << " Because of ";
ReasonNameGetter g(true);
cout << (*c)->reason()->accept_returning<std::pair<std::string, bool> >(g).first;
@@ -640,16 +641,19 @@ namespace
m != m_end ; ++m)
cout << " Masked by " << (*m)->description() << endl;
+ std::set<std::string> duplicates;
for (Constraints::ConstIterator c(u->unmet_constraints()->begin()),
c_end(u->unmet_constraints()->end()) ;
c != c_end ; ++c)
{
- cout << " Did not meet ";
- display_one_constraint(**c);
-
ReasonNameGetter g(false);
- cout << " from " << (*c)->reason()->accept_returning<std::pair<std::string, bool> >(g).first;
- cout << endl;
+ std::string s(constraint_as_string(**c) + " from " +
+ (*c)->reason()->accept_returning<std::pair<std::string, bool> >(g).first);
+
+ if (! duplicates.insert(s).second)
+ continue;
+
+ cout << " Did not meet " << s << endl;
if ((*c)->spec().if_package() && (*c)->spec().if_package()->additional_requirements_ptr() &&
(! match_package(*env, *(*c)->spec().if_package(), *u->package_id(), MatchPackageOptions())) &&
@@ -670,126 +674,98 @@ namespace
}
}
- struct DisplayOneUntakenVisitor
+ struct ShowJobsDisplayer
{
const std::tr1::shared_ptr<Environment> env;
const DisplayResolutionCommandLine & cmdline;
- const std::tr1::shared_ptr<const Resolution> resolution;
+ const ResolverLists & lists;
+ const bool all;
- DisplayOneUntakenVisitor(const std::tr1::shared_ptr<Environment> & e,
+ ShowJobsDisplayer(
+ const std::tr1::shared_ptr<Environment> & e,
const DisplayResolutionCommandLine & c,
- const std::tr1::shared_ptr<const Resolution> & r) :
+ const ResolverLists & l,
+ const bool a
+ ) :
env(e),
cmdline(c),
- resolution(r)
+ lists(l),
+ all(a)
{
}
- bool visit(const NothingNoChangeDecision &) const
+ bool visit(const SimpleInstallJob & job)
{
- return false;
- }
-
- bool visit(const ExistingNoChangeDecision &) const
- {
- return false;
- }
-
- bool visit(const ChangesToMakeDecision & d) const
- {
- display_one_installish(env, cmdline, d, resolution);
+ display_one_install(env, cmdline, job);
return true;
}
- bool visit(const UnableToMakeDecision & d) const
+ bool visit(const UsableJob & job, const bool indent = false)
{
- display_unable_to_make_decision(env, resolution, d);
- return true;
- }
- };
-
- bool display_one_untaken(
- const std::tr1::shared_ptr<Environment> & env,
- const DisplayResolutionCommandLine & cmdline,
- const UntakenInstallJob & job)
- {
- return job.resolution()->decision()->accept_returning<bool>(DisplayOneUntakenVisitor(
- env, cmdline, job.resolution()));
- }
-
- struct DisplayOneJobVisitor
- {
- const std::tr1::shared_ptr<Environment> env;
- const DisplayResolutionCommandLine & cmdline;
+ if (! all)
+ return false;
- DisplayOneJobVisitor(
- const std::tr1::shared_ptr<Environment> & e,
- const DisplayResolutionCommandLine & c) :
- env(e),
- cmdline(c)
- {
+ if (indent)
+ cout << " ";
+ cout << "- " << c::bold_normal() << job.resolution()->resolvent() << c::normal() << " now usable" << endl;
+ return true;
}
- bool visit(const PretendJob & job) const
+ bool visit(const UsableGroupJob & job)
{
- if (! cmdline.display_options.a_show_all_jobs.specified())
+ if (! all)
return false;
- display_special_job_decision(env, cmdline, "Pretend", job.decision()->origin_id());
-
+ 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;
}
- bool visit(const FetchJob & job) const
+ bool visit(const FetchJob & job)
{
- if (! cmdline.display_options.a_show_all_jobs.specified())
+ if (! all)
return false;
- display_special_job_decision(env, cmdline, "Fetch", job.decision()->origin_id());
-
+ cout << "- " << c::bold_normal() << job.resolution()->resolvent() << c::normal() << " fetch" << endl;
return true;
}
- bool visit(const UsableJob & job) const
+ bool visit(const ErrorJob &)
{
- if (! cmdline.display_options.a_show_all_jobs.specified())
- return false;
-
- cout << "- Can now use " << job.resolution()->resolvent() << endl;
-
- return true;
+ return false;
}
+ };
- bool visit(const SimpleInstallJob & job) const
+ struct JobNameVisitor
+ {
+ const std::string visit(const SimpleInstallJob & j) const
{
- display_one_install(env, cmdline, job);
- return true;
+ return "install " + stringify(*j.decision()->origin_id());
}
- bool visit(const SyncPointJob & job) const
+ const std::string visit(const UsableJob & j) const
{
- if (! cmdline.display_options.a_show_all_jobs.specified())
- return false;
+ return "usable " + stringify(j.resolution()->resolvent());
+ }
- cout << "- Sync point " << job.sync_point() << endl;
+ const std::string visit(const ErrorJob &) const
+ {
+ return "error";
+ }
- return true;
+ const std::string visit(const FetchJob & j) const
+ {
+ return "fetch " + stringify(*j.decision()->origin_id());
}
- bool visit(const UntakenInstallJob & job) const
+ const std::string visit(const UsableGroupJob & j) const
{
- return display_one_untaken(env, cmdline, job);
+ return "usable (" + stringify(std::distance(j.job_ids()->begin(), j.job_ids()->end())) + ")";
}
};
- bool display_one_job(
- const std::tr1::shared_ptr<Environment> & env,
- const DisplayResolutionCommandLine & cmdline,
- const std::tr1::shared_ptr<const Job> & job)
- {
- return job->accept_returning<bool>(DisplayOneJobVisitor(env, cmdline));
- }
-
void display_jobs(
const std::tr1::shared_ptr<Environment> & env,
const ResolverLists & lists,
@@ -799,21 +775,43 @@ namespace
cout << "These are the actions I will take, in order:" << endl << endl;
- bool shown_any(false);
- for (JobIDSequence::ConstIterator i(lists.ordered_job_ids()->begin()),
- i_end(lists.ordered_job_ids()->end()) ;
+ bool any(false);
+ for (JobIDSequence::ConstIterator i(lists.taken_job_ids()->begin()),
+ i_end(lists.taken_job_ids()->end()) ;
i != i_end ; ++i)
{
const std::tr1::shared_ptr<const Job> job(lists.jobs()->fetch(*i));
- shown_any |= display_one_job(env, cmdline, job);
+ ShowJobsDisplayer d(env, cmdline, lists, cmdline.display_options.a_show_all_jobs.specified() ||
+ ! job->used_existing_packages_when_ordering()->empty());
+ any |= job->accept_returning<bool>(d);
+
+ if (! job->used_existing_packages_when_ordering()->empty())
+ {
+ 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;
+ }
}
- if (! shown_any)
+ if (! any)
cout << "(nothing to do)" << endl;
cout << endl;
}
+ void display_one_error(
+ const std::tr1::shared_ptr<Environment> & env,
+ const DisplayResolutionCommandLine &,
+ const std::tr1::shared_ptr<const Resolution> & resolution,
+ const ErrorJob & j)
+ {
+ display_unable_to_make_decision(env, resolution, *j.decision());
+ }
+
void display_untaken(
const std::tr1::shared_ptr<Environment> & env,
const ResolverLists & lists,
@@ -821,7 +819,7 @@ namespace
{
Context context("When displaying untaken jobs:");
- if (lists.untaken_job_ids()->empty())
+ if (lists.untaken_job_ids()->empty() && lists.untaken_error_job_ids()->empty())
return;
cout << "I did not take the following:" << endl << endl;
@@ -830,55 +828,19 @@ namespace
i_end(lists.untaken_job_ids()->end()) ;
i != i_end ; ++i)
{
- const std::tr1::shared_ptr<const Job> job(lists.jobs()->fetch(*i));
- if (! display_one_job(env, cmdline, job))
- throw InternalError(PALUDIS_HERE, "who put something icky on the untaken list?");
- }
-
- cout << endl;
- }
-
- struct DisplayOneDecisionVisitor
- {
- const std::tr1::shared_ptr<Environment> env;
- const std::tr1::shared_ptr<const Resolution> resolution;
-
- DisplayOneDecisionVisitor(
- const std::tr1::shared_ptr<Environment> & e,
- const std::tr1::shared_ptr<const Resolution> & r) :
- env(e),
- resolution(r)
- {
+ const std::tr1::shared_ptr<const SimpleInstallJob> job(lists.jobs()->fetch_as<SimpleInstallJob>(*i));
+ display_one_install(env, cmdline, *job);
}
- void visit(const NothingNoChangeDecision &) const PALUDIS_ATTRIBUTE((noreturn))
- {
- throw InternalError(PALUDIS_HERE, "nothing no change?");
- }
-
- void visit(const ExistingNoChangeDecision &) const PALUDIS_ATTRIBUTE((noreturn))
- {
- throw InternalError(PALUDIS_HERE, "existing no change?");
- }
-
- void visit(const ChangesToMakeDecision &) const PALUDIS_ATTRIBUTE((noreturn))
- {
- throw InternalError(PALUDIS_HERE, "changes to make?");
- }
-
- void visit(const UnableToMakeDecision & d) const
+ for (JobIDSequence::ConstIterator i(lists.untaken_error_job_ids()->begin()),
+ i_end(lists.untaken_error_job_ids()->end()) ;
+ i != i_end ; ++i)
{
- display_unable_to_make_decision(env, resolution, d);
+ const std::tr1::shared_ptr<const ErrorJob> job(lists.jobs()->fetch_as<ErrorJob>(*i));
+ display_one_error(env, cmdline, job->resolution(), *job);
}
- };
- void display_one_decision(
- const std::tr1::shared_ptr<Environment> & env,
- const DisplayResolutionCommandLine &,
- const std::tr1::shared_ptr<const Resolution> & resolution,
- const Decision & decision)
- {
- decision.accept(DisplayOneDecisionVisitor(env, resolution));
+ cout << endl;
}
void display_errors(
@@ -888,15 +850,18 @@ namespace
{
Context context("When displaying errors:");
- if (lists.error_resolutions()->empty())
+ if (lists.taken_error_job_ids()->empty())
return;
cout << "I encountered the following errors:" << endl << endl;
- for (Resolutions::ConstIterator r(lists.error_resolutions()->begin()),
- r_end(lists.error_resolutions()->end()) ;
- r != r_end ; ++r)
- display_one_decision(env, cmdline, *r, *(*r)->decision());
+ 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);
+ }
cout << endl;
}
@@ -928,17 +893,20 @@ DisplayResolutionCommand::run(
cmdline.import_options.apply(env);
- int fd(destringify<int>(getenv_with_default("PALUDIS_SERIALISED_RESOLUTION_FD", "")));
- SafeIFStream deser_stream(fd);
- const std::string deser_str((std::istreambuf_iterator<char>(deser_stream)), std::istreambuf_iterator<char>());
- Deserialiser deserialiser(env.get(), deser_str);
- Deserialisation deserialisation("ResolverLists", deserialiser);
- ResolverLists lists(ResolverLists::deserialise(deserialisation));
-
- display_jobs(env, lists, cmdline);
- display_untaken(env, lists, cmdline);
- display_errors(env, lists, cmdline);
- display_explanations(env, lists, cmdline);
+ std::tr1::shared_ptr<ResolverLists> lists;
+ {
+ int fd(destringify<int>(getenv_with_default("PALUDIS_SERIALISED_RESOLUTION_FD", "")));
+ SafeIFStream deser_stream(fd);
+ const std::string deser_str((std::istreambuf_iterator<char>(deser_stream)), std::istreambuf_iterator<char>());
+ Deserialiser deserialiser(env.get(), deser_str);
+ Deserialisation deserialisation("ResolverLists", deserialiser);
+ lists = make_shared_copy(ResolverLists::deserialise(deserialisation));
+ }
+
+ display_jobs(env, *lists, cmdline);
+ display_untaken(env, *lists, cmdline);
+ display_errors(env, *lists, cmdline);
+ display_explanations(env, *lists, cmdline);
return 0;
}
diff --git a/src/clients/cave/cmd_execute_resolution.cc b/src/clients/cave/cmd_execute_resolution.cc
index e25c3f6..8365a7f 100644
--- a/src/clients/cave/cmd_execute_resolution.cc
+++ b/src/clients/cave/cmd_execute_resolution.cc
@@ -33,7 +33,11 @@
#include <paludis/util/iterator_funcs.hh>
#include <paludis/util/options.hh>
#include <paludis/util/simple_visitor_cast.hh>
+#include <paludis/util/simple_visitor-impl.hh>
#include <paludis/util/make_named_values.hh>
+#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/resolver/reason.hh>
#include <paludis/resolver/sanitised_dependencies.hh>
@@ -47,6 +51,8 @@
#include <paludis/resolver/jobs.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/package_id.hh>
#include <paludis/version_spec.hh>
#include <paludis/metadata_key.hh>
@@ -66,6 +72,7 @@
#include <list>
#include <cstdlib>
#include <algorithm>
+#include <tr1/unordered_map>
using namespace paludis;
using namespace cave;
@@ -116,14 +123,12 @@ namespace
}
};
- typedef std::list<std::tr1::shared_ptr<OutputManager> > CompletedOutputManagers;
-
- int do_pretend(
+ bool do_pretend(
const std::tr1::shared_ptr<Environment> & env,
const ExecuteResolutionCommandLine & cmdline,
const ChangesToMakeDecision & decision,
const int x, const int y,
- CompletedOutputManagers & completed_output_managers)
+ std::tr1::shared_ptr<OutputManager> & output_manager_goes_here)
{
Context context("When pretending for '" + stringify(*decision.origin_id()) + "':");
@@ -158,10 +163,10 @@ namespace
if (output_manager)
{
output_manager->nothing_more_to_come();
- completed_output_managers.push_back(output_manager);
+ output_manager_goes_here = output_manager;
}
- return retcode;
+ return 0 == retcode;
}
void starting_action(
@@ -190,12 +195,12 @@ namespace
cout << endl;
}
- int do_fetch(
+ bool do_fetch(
const std::tr1::shared_ptr<Environment> & env,
const ExecuteResolutionCommandLine & cmdline,
const ChangesToMakeDecision & decision,
const int x, const int y, bool normal_only,
- CompletedOutputManagers & completed_output_managers)
+ std::tr1::shared_ptr<OutputManager> & output_manager_goes_here)
{
const std::tr1::shared_ptr<const PackageID> id(decision.origin_id());
Context context("When fetching for '" + stringify(*id) + "':");
@@ -232,20 +237,20 @@ namespace
if (output_manager)
{
output_manager->nothing_more_to_come();
- completed_output_managers.push_back(output_manager);
+ output_manager_goes_here = output_manager;
}
done_action("fetch (" + std::string(normal_only ? "regular parts" : "extra parts") + ")", decision, 0 == retcode);
- return retcode;
+ return 0 == retcode;
}
- int do_install(
+ 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 int x, const int y,
- CompletedOutputManagers & completed_output_managers)
+ std::tr1::shared_ptr<OutputManager> & output_manager_goes_here)
{
std::string destination_string, action_string;
switch (resolution->resolvent().destination_type())
@@ -332,20 +337,18 @@ namespace
if (output_manager)
{
output_manager->nothing_more_to_come();
- completed_output_managers.push_back(output_manager);
+ output_manager_goes_here = output_manager;
}
done_action(action_string, decision, 0 == retcode);
- return retcode;
+ return 0 == retcode;
}
struct JobCounts
{
- int x_pretends, y_pretends, x_fetches, y_fetches, x_installs, y_installs;
+ int x_fetches, y_fetches, x_installs, y_installs;
JobCounts() :
- x_pretends(0),
- y_pretends(0),
x_fetches(0),
y_fetches(0),
x_installs(0),
@@ -353,11 +356,6 @@ namespace
{
}
- void visit(const PretendJob &)
- {
- ++y_pretends;
- }
-
void visit(const SimpleInstallJob &)
{
++y_installs;
@@ -372,153 +370,367 @@ namespace
{
}
- void visit(const SyncPointJob &)
+ void visit(const UsableGroupJob &)
{
}
- void visit(const UntakenInstallJob &)
+ void visit(const ErrorJob &)
{
}
};
- struct PerformJobs
+ typedef std::tr1::unordered_map<JobID, std::tr1::shared_ptr<JobState>, Hash<JobID> > JobStateMap;
+ typedef std::list<std::tr1::shared_ptr<JobPendingState> > PendingJobsList;
+
+ struct DoOneTakenVisitor
{
const std::tr1::shared_ptr<Environment> env;
const ExecuteResolutionCommandLine & cmdline;
JobCounts & counts;
- CompletedOutputManagers & completed_output_managers;
+ std::tr1::shared_ptr<JobState> & state;
+ JobStateMap & job_state_map;
- bool done_any_pretends;
- bool done_any_installs;
- int retcode;
-
- PerformJobs(
+ DoOneTakenVisitor(
const std::tr1::shared_ptr<Environment> & e,
const ExecuteResolutionCommandLine & c,
JobCounts & k,
- CompletedOutputManagers & m) :
+ std::tr1::shared_ptr<JobState> & s,
+ JobStateMap & m) :
env(e),
cmdline(c),
counts(k),
- completed_output_managers(m),
- done_any_pretends(false),
- done_any_installs(false),
- retcode(0)
+ state(s),
+ job_state_map(m)
{
}
- bool visit(const PretendJob & job)
+ bool visit(const SimpleInstallJob & job)
{
- if (! done_any_pretends)
+ 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.decision(), counts.x_installs, counts.y_installs,
+ false, fetch_output_manager_goes_here))
{
- done_any_pretends = true;
+ 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 (0 != env->perform_hook(Hook("pretend_all_pre")
- ("TARGETS", join(cmdline.begin_parameters(), cmdline.end_parameters(), " "))
- ).max_exit_status())
- throw ActionAbortedError("Aborted by hook");
+ if (! do_install(env, cmdline, job.resolution(),
+ *job.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;
+ }
+ }
- std::cout << "Executing pretend actions: " << std::flush;
+ bool visit(const FetchJob & job)
+ {
+ std::tr1::shared_ptr<OutputManager> output_manager_goes_here;
+
+ ++counts.x_fetches;
+ if (! do_fetch(env, cmdline, *job.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;
}
+ }
- retcode |= do_pretend(env, cmdline, *job.decision(), ++counts.x_pretends, counts.y_pretends,
- completed_output_managers);
+ bool visit(const ErrorJob &)
+ {
+ state.reset(new JobFailedState(state->job()));
+ return false;
+ }
- /* a pretend failing doesn't abort us yet */
+ bool visit(const UsableJob &)
+ {
+ state.reset(new JobSucceededState(state->job()));
return true;
}
- bool visit(const SimpleInstallJob & job)
+ bool visit(const UsableGroupJob & job)
{
- if (0 != retcode)
- return false;
+ bool result(true);
- if (! done_any_installs)
+ for (JobIDSequence::ConstIterator i(job.job_ids()->begin()), i_end(job.job_ids()->end()) ;
+ i != i_end ; ++i)
{
- done_any_installs = true;
+ JobStateMap::iterator s(job_state_map.find(*i));
+ if (s == job_state_map.end())
+ throw InternalError(PALUDIS_HERE, "missing state");
- 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");
+ 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;
- /* not all of the fetch is done in the background */
- retcode |= do_fetch(env, cmdline, *job.decision(), counts.x_installs, counts.y_installs, false,
- completed_output_managers);
- if (0 != retcode)
- return false;
+ cout << endl;
+ cout << c::bold_blue() << counts.x_installs << " of " << counts.y_installs << ": Skipping install of "
+ << *job.decision()->origin_id() << c::normal() << endl;
+ cout << endl;
- retcode |= do_install(env, cmdline, job.resolution(),
- *job.decision(), counts.x_installs, counts.y_installs,
- completed_output_managers);
- if (0 != retcode)
- return false;
+ state.reset(new JobSkippedState(state->job()));
+ }
- return true;
+ void visit(const FetchJob &)
+ {
+ ++counts.x_fetches;
+
+ state.reset(new JobSkippedState(state->job()));
}
- bool visit(const FetchJob & job)
+ void visit(const ErrorJob &)
{
- if (0 != retcode)
- return false;
+ state.reset(new JobSkippedState(state->job()));
+ }
- retcode |= do_fetch(env, cmdline, *job.decision(), ++counts.x_fetches, counts.y_fetches, true,
- completed_output_managers);
- if (0 != retcode)
- return false;
+ void visit(const UsableJob &)
+ {
+ state.reset(new JobSkippedState(state->job()));
+ }
- return true;
+ 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()));
}
+ };
+
+ int execute_update_world(
+ const std::tr1::shared_ptr<Environment> & env,
+ const ResolverLists &,
+ const ExecuteResolutionCommandLine & cmdline)
+ {
+ if (cmdline.execution_options.a_preserve_world.specified())
+ return 0;
+
+ cout << endl << c::bold_green() << "Updating world" << c::normal() << endl << endl;
+
+ std::string command(cmdline.program_options.a_update_world_program.argument());
+ if (command.empty())
+ command = "$CAVE update-world";
- bool visit(const SyncPointJob & job)
+ bool any(false);
+ if (cmdline.a_set.specified())
{
- switch (job.sync_point())
+ command.append(" --set");
+ for (args::ArgsHandler::ParametersConstIterator a(cmdline.begin_parameters()),
+ a_end(cmdline.end_parameters()) ;
+ a != a_end ; ++a)
{
- case sp_done_installs:
- {
- if (0 != env->perform_hook(Hook("install_all_post")
- ("TARGETS", join(cmdline.begin_parameters(), cmdline.end_parameters(), " "))
- ).max_exit_status())
- throw ActionAbortedError("Aborted by hook");
- }
- break;
+ if (*a == "world" || *a == "system" || *a == "security"
+ || *a == "everything" || *a == "insecurity"
+ || *a == "installed-packages" || *a == "installed-slots")
+ cout << "* Special set '" << *a << "' does not belong in world" << endl;
+ else
+ {
+ any = true;
+ cout << "* Adding '" << *a << "'" << endl;
+ command.append(" " + *a);
+ }
+ }
+ }
+ else
+ {
+ for (args::ArgsHandler::ParametersConstIterator a(cmdline.begin_parameters()),
+ a_end(cmdline.end_parameters()) ;
+ a != a_end ; ++a)
+ {
+ PackageDepSpec spec(parse_user_package_dep_spec(*a, env.get(), UserPackageDepSpecOptions()));
+ if (package_dep_spec_has_properties(spec, make_named_values<PackageDepSpecProperties>(
+ value_for<n::has_additional_requirements>(false),
+ value_for<n::has_category_name_part>(false),
+ value_for<n::has_from_repository>(false),
+ value_for<n::has_in_repository>(false),
+ value_for<n::has_installable_to_path>(false),
+ value_for<n::has_installable_to_repository>(false),
+ value_for<n::has_installed_at_path>(false),
+ value_for<n::has_package>(true),
+ value_for<n::has_package_name_part>(false),
+ value_for<n::has_slot_requirement>(false),
+ value_for<n::has_tag>(indeterminate),
+ value_for<n::has_version_requirements>(false)
+ )))
+ {
+ any = true;
+ cout << "* Adding '" << spec << "'" << endl;
+ command.append(" " + stringify(spec));
+ }
+ else
+ {
+ cout << "* Not adding '" << spec << "'" << endl;
+ }
+ }
+ }
- case sp_done_pretends:
- {
- std::cout << std::endl;
+ if (any)
+ {
+ paludis::Command cmd(command);
+ if (0 != run_command(cmd))
+ throw ActionAbortedError("Updating world failed");
+ }
- 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 0;
+ }
- if ((0 != retcode) || (cmdline.a_pretend.specified()))
- return false;
- }
- break;
+ struct Populator
+ {
+ 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)
+ {
+ }
+
+ void common() const
+ {
+ 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 (pending)
+ pending->push_back(state);
+ }
+
+ void visit(const SimpleInstallJob &) const
+ {
+ common();
+ }
+
+ void visit(const UsableJob &) const
+ {
+ common();
+ }
+
+ void visit(const FetchJob &) const
+ {
+ common();
+ }
+
+ void visit(const ErrorJob &) const
+ {
+ common();
+ }
+
+ void visit(const UsableGroupJob & j) const
+ {
+ common();
- case last_sp:
- break;
+ for (JobIDSequence::ConstIterator i(j.job_ids()->begin()), i_end(j.job_ids()->end()) ;
+ i != i_end ; ++i)
+ {
+ const std::tr1::shared_ptr<const Job> k(lists.jobs()->fetch(*i));
+ k->accept(Populator(k, lists, job_state_map, 0));
}
+ }
+ };
- return true;
+ struct JobStateChecker
+ {
+ bool visit(const JobPendingState &) const PALUDIS_ATTRIBUTE((noreturn))
+ {
+ throw InternalError(PALUDIS_HERE, "still pending");
}
- bool visit(const UntakenInstallJob &)
+ bool visit(const JobFailedState &) const
{
- return true;
+ return false;
}
- bool visit(const UsableJob &)
+ bool visit(const JobSkippedState &) const
+ {
+ return false;
+ }
+
+ bool visit(const JobSucceededState &) const
{
return true;
}
};
- int execute_resolution_main(
+ int execute_taken(
const std::tr1::shared_ptr<Environment> & env,
const ResolverLists & lists,
const ExecuteResolutionCommandLine & cmdline)
@@ -526,94 +738,191 @@ namespace
int retcode(0);
JobCounts counts;
- CompletedOutputManagers completed_output_managers;
+ JobStateMap job_state_map;
+ PendingJobsList pending;
- for (JobIDSequence::ConstIterator c(lists.ordered_job_ids()->begin()),
- c_end(lists.ordered_job_ids()->end()) ;
+ 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);
-
- PerformJobs perform_jobs(env, cmdline, counts, completed_output_managers);
- for (JobIDSequence::ConstIterator c(lists.ordered_job_ids()->begin()),
- c_end(lists.ordered_job_ids()->end()) ;
- c != c_end ; ++c)
- if (! lists.jobs()->fetch(*c)->accept_returning<bool>(perform_jobs))
- break;
-
- completed_output_managers.clear();
+ {
+ const std::tr1::shared_ptr<const Job> job(lists.jobs()->fetch(*c));
+ job->accept(counts);
+ job->accept(Populator(job, lists, job_state_map, &pending));
+ }
- retcode |= perform_jobs.retcode;
- if ((0 != retcode) || (cmdline.a_pretend.specified()))
- return retcode;
+ 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");
- if (! cmdline.execution_options.a_preserve_world.specified())
+ for (PendingJobsList::iterator p(pending.begin()), p_next(p), p_end(pending.end()) ;
+ p != p_end ; p = p_next)
{
- cout << endl << c::bold_green() << "Updating world" << c::normal() << endl << endl;
-
- std::string command(cmdline.program_options.a_update_world_program.argument());
- if (command.empty())
- command = "$CAVE update-world";
+ ++p_next;
- bool any(false);
- if (cmdline.a_set.specified())
+ 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)
{
- command.append(" --set");
- for (args::ArgsHandler::ParametersConstIterator a(cmdline.begin_parameters()),
- a_end(cmdline.end_parameters()) ;
- a != a_end ; ++a)
+ 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 (*a == "world" || *a == "system" || *a == "security"
- || *a == "everything" || *a == "insecurity"
- || *a == "installed-packages" || *a == "installed-slots")
- cout << "* Special set '" << *a << "' does not belong in world" << endl;
- else
+ 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());
+ }
+ 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())))
{
- any = true;
- cout << "* Adding '" << *a << "'" << endl;
- command.append(" " + *a);
+ skipped_because_of = after_job;
+ break;
}
}
}
+
+ 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)
+ {
+ DoOneSkippedVisitor v(env, cmdline, counts, s->second, job_state_map);
+ s->second->job()->accept(v);
+ retcode |= 1;
+ }
else
{
- for (args::ArgsHandler::ParametersConstIterator a(cmdline.begin_parameters()),
- a_end(cmdline.end_parameters()) ;
- a != a_end ; ++a)
+ DoOneTakenVisitor v(env, cmdline, counts, s->second, job_state_map);
+ if (! s->second->job()->accept_returning<bool>(v))
{
- PackageDepSpec spec(parse_user_package_dep_spec(*a, env.get(), UserPackageDepSpecOptions()));
- if (package_dep_spec_has_properties(spec, make_named_values<PackageDepSpecProperties>(
- value_for<n::has_additional_requirements>(false),
- value_for<n::has_category_name_part>(false),
- value_for<n::has_from_repository>(false),
- value_for<n::has_in_repository>(false),
- value_for<n::has_installable_to_path>(false),
- value_for<n::has_installable_to_repository>(false),
- value_for<n::has_installed_at_path>(false),
- value_for<n::has_package>(true),
- value_for<n::has_package_name_part>(false),
- value_for<n::has_slot_requirement>(false),
- value_for<n::has_tag>(indeterminate),
- value_for<n::has_version_requirements>(false)
- )))
- {
- any = true;
- cout << "* Adding '" << spec << "'" << endl;
- command.append(" " + stringify(spec));
- }
- else
- {
- cout << "* Not adding '" << spec << "'" << endl;
- }
+ retcode |= 1;
+
+ if (cmdline.execution_options.a_continue_on_failure.argument() == "never")
+ break;
}
}
+ }
- if (any)
- {
- paludis::Command cmd(command);
- if (0 != run_command(cmd))
- throw ActionAbortedError("Updating world failed");
- }
+ if (0 != env->perform_hook(Hook("install_all_post")
+ ("TARGETS", join(cmdline.begin_parameters(), cmdline.end_parameters(), " "))
+ ).max_exit_status())
+ throw ActionAbortedError("Aborted by hook");
+
+ return retcode;
+ }
+
+ struct DoOnePretendVisitor
+ {
+ const std::tr1::shared_ptr<Environment> env;
+ const ExecuteResolutionCommandLine & cmdline;
+ JobCounts & counts;
+
+ DoOnePretendVisitor(
+ const std::tr1::shared_ptr<Environment> & e,
+ const ExecuteResolutionCommandLine & c,
+ JobCounts & k) :
+ env(e),
+ cmdline(c),
+ counts(k)
+ {
}
+
+ bool visit(const SimpleInstallJob & c) const
+ {
+ std::tr1::shared_ptr<OutputManager> output_manager_goes_here;
+ return do_pretend(env, cmdline, *c.decision(), ++counts.x_installs, counts.y_installs,
+ output_manager_goes_here);
+ }
+
+ 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(
+ const std::tr1::shared_ptr<Environment> & env,
+ const ResolverLists & lists,
+ const ExecuteResolutionCommandLine & cmdline)
+ {
+ bool failed(false);
+ JobCounts counts;
+
+ 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");
+
+ std::cout << "Executing pretend actions: " << std::flush;
+
+ for (JobIDSequence::ConstIterator c(lists.taken_job_ids()->begin()),
+ c_end(lists.taken_job_ids()->end()) ;
+ c != c_end ; ++c)
+ failed = failed || ! lists.jobs()->fetch(*c)->accept_returning<bool>(DoOnePretendVisitor(env, cmdline, counts));
+
+ 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;
+ }
+
+ int execute_resolution_main(
+ const std::tr1::shared_ptr<Environment> & env,
+ const ResolverLists & lists,
+ const ExecuteResolutionCommandLine & cmdline)
+ {
+ int retcode(0);
+
+ retcode |= execute_pretends(env, lists, cmdline);
+ if (0 != retcode || cmdline.a_pretend.specified())
+ return retcode;
+
+ retcode |= execute_taken(env, lists, cmdline);
+
+ if (0 != retcode)
+ return retcode;
+
+ retcode |= execute_update_world(env, lists, cmdline);
return retcode;
}
@@ -625,7 +934,6 @@ namespace
Context context("When executing chosen resolution:");
int retcode(0);
-
if (0 != env->perform_hook(Hook("install_task_execute_pre")
("TARGETS", join(cmdline.begin_parameters(), cmdline.end_parameters(), " "))
).max_exit_status())
@@ -683,14 +991,17 @@ ExecuteResolutionCommand::run(
cmdline.import_options.apply(env);
- int fd(destringify<int>(getenv_with_default("PALUDIS_SERIALISED_RESOLUTION_FD", "")));
- SafeIFStream deser_stream(fd);
- const std::string deser_str((std::istreambuf_iterator<char>(deser_stream)), std::istreambuf_iterator<char>());
- Deserialiser deserialiser(env.get(), deser_str);
- Deserialisation deserialisation("ResolverLists", deserialiser);
- ResolverLists lists(ResolverLists::deserialise(deserialisation));
+ std::tr1::shared_ptr<ResolverLists> lists;
+ {
+ int fd(destringify<int>(getenv_with_default("PALUDIS_SERIALISED_RESOLUTION_FD", "")));
+ SafeIFStream deser_stream(fd);
+ const std::string deser_str((std::istreambuf_iterator<char>(deser_stream)), std::istreambuf_iterator<char>());
+ Deserialiser deserialiser(env.get(), deser_str);
+ Deserialisation deserialisation("ResolverLists", deserialiser);
+ lists = make_shared_copy(ResolverLists::deserialise(deserialisation));
+ }
- return execute_resolution(env, lists, cmdline);
+ return execute_resolution(env, *lists, cmdline);
}
std::tr1::shared_ptr<args::ArgsHandler>
@@ -699,4 +1010,3 @@ ExecuteResolutionCommand::make_doc_cmdline()
return make_shared_ptr(new ExecuteResolutionCommandLine);
}
-
diff --git a/src/clients/cave/cmd_resolve_cmdline.cc b/src/clients/cave/cmd_resolve_cmdline.cc
index 3b186e6..e795419 100644
--- a/src/clients/cave/cmd_resolve_cmdline.cc
+++ b/src/clients/cave/cmd_resolve_cmdline.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2009 Ciaran McCreesh
+ * 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
@@ -88,12 +88,11 @@ ResolveCommandLineResolutionOptions::ResolveCommandLineResolutionOptions(args::A
("never", 'n', "Never")
("if-transient", 't', "Only if the installed package is transient "
"(e.g. from 'importare') (default if --everything)")
- ("if-same", 's', "If it is the same as the proposed replacement "
- "(default if --complete)")
+ ("if-same", 's', "If it is the same as the proposed replacement")
("if-same-version", 'v', "If it is the same version as the proposed replacement")
- ("if-possible", 'p', "If possible"),
+ ("if-possible", 'p', "If possible (default if --lazy)"),
- "if-possible"
+ "if-same"
),
a_reinstall_scm(&g_keep_options, "reinstall-scm", 'R',
"Select whether to reinstall SCM packages that would otherwise be kept",
@@ -240,12 +239,11 @@ ResolveCommandLineExecutionOptions::ResolveCommandLineExecutionOptions(args::Arg
a_continue_on_failure(&g_failure_options, "continue-on-failure", '\0',
"Whether to continue after an error occurs",
args::EnumArg::EnumArgOptions
- ("if-fetching", "Only if we are just fetching packages")
("never", "Never")
("if-satisfied", "If remaining packages' dependencies are satisfied")
("if-independent", "If remaining packages do not depend upon any failing package")
("always", "Always (dangerous)"),
- "if-fetching"),
+ "never"),
g_phase_options(this, "Phase Options", "Options controlling which phases to execute. No sanity checking "
"is done, allowing you to shoot as many feet off as you desire. Phase names do not have the "
@@ -352,6 +350,8 @@ ResolveCommandLineResolutionOptions::apply_shortcuts()
if (a_lazy.specified())
{
+ if (! a_keep.specified())
+ a_keep.set_argument("if-possible");
if (! a_target_slots.specified())
a_target_slots.set_argument("best");
if (! a_slots.specified())
@@ -362,8 +362,6 @@ ResolveCommandLineResolutionOptions::apply_shortcuts()
if (a_complete.specified())
{
- if (! a_keep.specified())
- a_keep.set_argument("if-same");
if (! a_target_slots.specified())
a_target_slots.set_argument("all");
if (! a_slots.specified())
diff --git a/src/clients/cave/resolve_common.cc b/src/clients/cave/resolve_common.cc
index 363a2f3..133dc41 100644
--- a/src/clients/cave/resolve_common.cc
+++ b/src/clients/cave/resolve_common.cc
@@ -1199,7 +1199,7 @@ paludis::cave::resolve_common(
retcode |= display_resolution(env, *resolver->lists(), resolution_options,
display_options, program_options, keys_if_import, targets);
- if (! resolver->lists()->error_resolutions()->empty())
+ if (! resolver->lists()->taken_error_job_ids()->empty())
retcode |= 1;
if (0 == retcode)