aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-07-14 09:02:21 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-07-14 09:02:21 +0100
commit2b7cc3f84df9a6a28ecf65c68ede7db9680a10b1 (patch)
tree29c079193d3a30555c79cd296eeb33efea8e1a87
parente930472b734ca2b0de73e09b89ed5177f1d61954 (diff)
downloadpaludis-2b7cc3f84df9a6a28ecf65c68ede7db9680a10b1.tar.gz
paludis-2b7cc3f84df9a6a28ecf65c68ede7db9680a10b1.tar.xz
Impose continue-on-failure reqs for uninstalls
Fixes: ticket:915
-rw-r--r--paludis/resolver/orderer.cc59
-rw-r--r--paludis/resolver/resolver_TEST_continue_on_failure.cc71
2 files changed, 109 insertions, 21 deletions
diff --git a/paludis/resolver/orderer.cc b/paludis/resolver/orderer.cc
index 1d290f4..2b34483 100644
--- a/paludis/resolver/orderer.cc
+++ b/paludis/resolver/orderer.cc
@@ -58,7 +58,7 @@ using namespace paludis;
using namespace paludis::resolver;
typedef std::tr1::unordered_map<NAGIndex, std::tr1::shared_ptr<const ChangeOrRemoveDecision>, Hash<NAGIndex> > ChangeOrRemoveIndices;
-typedef std::tr1::unordered_map<NAGIndex, JobNumber, Hash<NAGIndex> > InstallJobNumbers;
+typedef std::tr1::unordered_map<NAGIndex, JobNumber, Hash<NAGIndex> > ChangeOrRemoveJobNumbers;
typedef std::tr1::unordered_map<Resolvent, JobNumber, Hash<Resolvent> > FetchJobNumbers;
namespace paludis
@@ -71,7 +71,7 @@ namespace paludis
const std::tr1::shared_ptr<Resolved> resolved;
ChangeOrRemoveIndices change_or_remove_indices;
FetchJobNumbers fetch_job_numbers;
- InstallJobNumbers install_job_numbers;
+ ChangeOrRemoveJobNumbers change_or_remove_job_numbers;
Implementation(
const Environment * const e,
@@ -668,9 +668,10 @@ namespace
void populate_requirements(
const std::tr1::shared_ptr<const NAG> & nag,
- const InstallJobNumbers & install_job_numbers,
+ const ChangeOrRemoveJobNumbers & change_or_remove_job_numbers,
const NAGIndex & index,
const std::tr1::shared_ptr<JobRequirements> & requirements,
+ const bool is_uninstall,
const bool recursing,
RecursedRequirements & recursed)
{
@@ -679,10 +680,10 @@ namespace
e_end(nag->end_edges_from(index)) ;
e != e_end ; ++e)
{
- if ((! e->second.build_all_met()) || (! e->second.run_all_met()))
+ if ((! e->second.build_all_met()) || (! e->second.run_all_met()) || is_uninstall)
{
- InstallJobNumbers::const_iterator n(install_job_numbers.find(e->first));
- if (n != install_job_numbers.end())
+ ChangeOrRemoveJobNumbers::const_iterator n(change_or_remove_job_numbers.find(e->first));
+ if (n != change_or_remove_job_numbers.end())
requirements->push_back(make_named_values<JobRequirement>(
n::job_number() = n->second,
n::required_if() = JobRequirementIfs() + jri_require_for_satisfied
@@ -690,18 +691,18 @@ namespace
}
}
- if (recursed.insert(index).second)
+ if ((! is_uninstall) && recursed.insert(index).second)
for (NAG::EdgesFromConstIterator e(nag->begin_edges_from(index)),
e_end(nag->end_edges_from(index)) ;
e != e_end ; ++e)
{
- InstallJobNumbers::const_iterator n(install_job_numbers.find(e->first));
- if (n != install_job_numbers.end())
+ ChangeOrRemoveJobNumbers::const_iterator n(change_or_remove_job_numbers.find(e->first));
+ if (n != change_or_remove_job_numbers.end())
requirements->push_back(make_named_values<JobRequirement>(
n::job_number() = n->second,
n::required_if() = JobRequirementIfs() + jri_require_for_independent
));
- populate_requirements(nag, install_job_numbers, e->first, requirements, true, recursed);
+ populate_requirements(nag, change_or_remove_job_numbers, e->first, requirements, is_uninstall, true, recursed);
}
}
}
@@ -765,17 +766,17 @@ namespace
{
const std::tr1::shared_ptr<const Resolved> resolved;
FetchJobNumbers & fetch_job_numbers;
- InstallJobNumbers & install_job_numbers;
+ ChangeOrRemoveJobNumbers & change_or_remove_job_numbers;
const NAGIndex index;
ExtraScheduler(
const std::tr1::shared_ptr<const Resolved> & r,
FetchJobNumbers & f,
- InstallJobNumbers & i,
+ ChangeOrRemoveJobNumbers & i,
const NAGIndex & v) :
resolved(r),
fetch_job_numbers(f),
- install_job_numbers(i),
+ change_or_remove_job_numbers(i),
index(v)
{
}
@@ -802,10 +803,11 @@ namespace
RecursedRequirements recursed;
populate_requirements(
resolved->nag(),
- install_job_numbers,
+ change_or_remove_job_numbers,
index,
requirements,
false,
+ false,
recursed
);
@@ -823,7 +825,7 @@ namespace
replacing
))));
- install_job_numbers.insert(std::make_pair(index, install_job_n));
+ change_or_remove_job_numbers.insert(std::make_pair(index, install_job_n));
}
return;
@@ -834,10 +836,11 @@ namespace
RecursedRequirements recursed;
populate_requirements(
resolved->nag(),
- install_job_numbers,
+ change_or_remove_job_numbers,
index,
requirements,
false,
+ false,
recursed
);
@@ -863,10 +866,24 @@ namespace
i != i_end ; ++i)
removing->push_back((*i)->uniquely_identifying_spec());
- resolved->job_lists()->execute_job_list()->append(make_shared_ptr(new UninstallJob(
- make_shared_ptr(new JobRequirements),
- removing
- )));
+ const std::tr1::shared_ptr<JobRequirements> requirements(new JobRequirements);
+ RecursedRequirements recursed;
+ populate_requirements(
+ resolved->nag(),
+ change_or_remove_job_numbers,
+ index,
+ requirements,
+ true,
+ false,
+ recursed
+ );
+
+ JobNumber uninstall_job_n(resolved->job_lists()->execute_job_list()->append(make_shared_ptr(new UninstallJob(
+ requirements,
+ removing
+ ))));
+
+ change_or_remove_job_numbers.insert(std::make_pair(index, uninstall_job_n));
}
};
}
@@ -897,7 +914,7 @@ Orderer::_schedule(
throw InternalError(PALUDIS_HERE, "bad index.role");
} while (false);
- d->accept(ExtraScheduler(_imp->resolved, _imp->fetch_job_numbers, _imp->install_job_numbers, index));
+ d->accept(ExtraScheduler(_imp->resolved, _imp->fetch_job_numbers, _imp->change_or_remove_job_numbers, index));
}
namespace
diff --git a/paludis/resolver/resolver_TEST_continue_on_failure.cc b/paludis/resolver/resolver_TEST_continue_on_failure.cc
index b4d7ad0..7daedf2 100644
--- a/paludis/resolver/resolver_TEST_continue_on_failure.cc
+++ b/paludis/resolver/resolver_TEST_continue_on_failure.cc
@@ -159,5 +159,76 @@ namespace test_cases
"2 satisfied independent always, 3 satisfied, 4 independent, 3 independent");
}
} test_continue_on_failure_false(false), test_continue_on_failure_true(true);
+
+ struct TestUninstallContinueOnFailure : ResolverContinueOnFailureTestCase
+ {
+ TestUninstallContinueOnFailure() :
+ ResolverContinueOnFailureTestCase("uninstall continue on failure")
+ {
+ install("continue-on-failure-uninstall", "dep-of-dep", "1")->build_dependencies_key()->set_from_string("");
+ install("continue-on-failure-uninstall", "dep", "1")->build_dependencies_key()->set_from_string("continue-on-failure-uninstall/dep-of-dep");
+ install("continue-on-failure-uninstall", "target", "1")->build_dependencies_key()->set_from_string("continue-on-failure-uninstall/dep");
+ install("continue-on-failure-uninstall", "needs-target", "1")->build_dependencies_key()->set_from_string("continue-on-failure-uninstall/target");
+
+ allowed_to_remove_names->insert(QualifiedPackageName("continue-on-failure-uninstall/dep-of-dep"));
+ allowed_to_remove_names->insert(QualifiedPackageName("continue-on-failure-uninstall/dep"));
+ allowed_to_remove_names->insert(QualifiedPackageName("continue-on-failure-uninstall/target"));
+ allowed_to_remove_names->insert(QualifiedPackageName("continue-on-failure-uninstall/needs-target"));
+
+ remove_if_dependent_names->insert(QualifiedPackageName("continue-on-failure-uninstall/dep-of-dep"));
+ remove_if_dependent_names->insert(QualifiedPackageName("continue-on-failure-uninstall/dep"));
+ remove_if_dependent_names->insert(QualifiedPackageName("continue-on-failure-uninstall/target"));
+ remove_if_dependent_names->insert(QualifiedPackageName("continue-on-failure-uninstall/needs-target"));
+ }
+
+ void run()
+ {
+ std::tr1::shared_ptr<const Resolved> resolved(get_resolved(BlockDepSpec(
+ "!continue-on-failure-uninstall/target",
+ parse_user_package_dep_spec("continue-on-failure-uninstall/target", &env, UserPackageDepSpecOptions()),
+ false)));
+
+ check_resolved(resolved,
+ n::taken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .remove(QualifiedPackageName("continue-on-failure-uninstall/needs-target"))
+ .remove(QualifiedPackageName("continue-on-failure-uninstall/target"))
+ .remove(QualifiedPackageName("continue-on-failure-uninstall/dep"))
+ .remove(QualifiedPackageName("continue-on-failure-uninstall/dep-of-dep"))
+ .finished()),
+ n::taken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::taken_unconfirmed_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::taken_unorderable_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_change_or_remove_decisions() = make_shared_copy(DecisionChecks()
+ .finished()),
+ n::untaken_unable_to_make_decisions() = make_shared_copy(DecisionChecks()
+ .finished())
+ );
+
+ TEST_CHECK_EQUAL(resolved->job_lists()->execute_job_list()->length(), 4);
+
+ const UninstallJob * const needs_target_job(simple_visitor_cast<const UninstallJob>(**resolved->job_lists()->execute_job_list()->fetch(0)));
+ TEST_CHECK(needs_target_job);
+ TEST_CHECK_EQUAL(join(needs_target_job->requirements()->begin(), needs_target_job->requirements()->end(), ", ", stringify_req),
+ "");
+
+ const UninstallJob * const target_job(simple_visitor_cast<const UninstallJob>(**resolved->job_lists()->execute_job_list()->fetch(1)));
+ TEST_CHECK(target_job);
+ TEST_CHECK_EQUAL(join(target_job->requirements()->begin(), target_job->requirements()->end(), ", ", stringify_req),
+ "0 satisfied");
+
+ const UninstallJob * const dep_job(simple_visitor_cast<const UninstallJob>(**resolved->job_lists()->execute_job_list()->fetch(2)));
+ TEST_CHECK(dep_job);
+ TEST_CHECK_EQUAL(join(dep_job->requirements()->begin(), dep_job->requirements()->end(), ", ", stringify_req),
+ "1 satisfied");
+
+ const UninstallJob * const dep_of_dep_job(simple_visitor_cast<const UninstallJob>(**resolved->job_lists()->execute_job_list()->fetch(3)));
+ TEST_CHECK(dep_of_dep_job);
+ TEST_CHECK_EQUAL(join(dep_of_dep_job->requirements()->begin(), dep_of_dep_job->requirements()->end(), ", ", stringify_req),
+ "2 satisfied");
+ }
+ } test_uninstall_continue_on_failure_uninstall;
}