Permalink
Browse files

[App::Pls] make .fetch non-recursive

This took some hacking, and I'm not sure I got it completely right.
But .fetch now only does the project itself, and not its dependencies,
because the dependencies aren't know until the project is fetched.
Other changes had to be made to make sure we didn't end up recursing
forever with mutually dependent projects.
  • Loading branch information...
1 parent b115c6c commit 7522692059e60027fdb9032036fd01266c654610 @masak committed Nov 12, 2010
Showing with 35 additions and 33 deletions.
  1. +32 −11 lib/App/Pls.pm
  2. +3 −22 t/subcommands/fetch.t
View
@@ -94,23 +94,24 @@ class App::Pls::Core {
return $!projects.state-of($project);
}
+ method !assert-no-cycle($project --> Result) {
+ return failure
+ if %*seen-projects{$project}++;
+ return failure
+ if self!assert-no-cycle(any $!projects.deps-of($project))
+ == failure;
+ return success;
+ }
+
method fetch(*@projects --> Result) {
for @projects -> $project {
- my %*seen-projects;
return failure
if self!fetch-helper($project) == failure;
}
return success;
}
method !fetch-helper($project --> Result) {
- %*seen-projects{$project}++;
- for $!projects.deps-of($project) -> $dep {
- return failure
- if %*seen-projects{$dep};
- return failure
- if self!fetch-helper($dep) == failure;
- }
if $!projects.reached-state($project, 'fetched') {
return success;
}
@@ -123,11 +124,25 @@ class App::Pls::Core {
}
}
+ method !fetch-all-dependencies($project --> Result) {
+ return failure
+ if self!fetch-helper($project) == failure;
+ for $!projects.deps-of($project) -> $dep {
+ return failure
+ if self!fetch-all-dependencies($dep) == failure;
+ }
+ return success;
+ }
+
method build(*@projects) {
for @projects -> $project {
- my %*seen-projects;
return failure
if self!fetch-helper($project) == failure;
+ my %*seen-projects;
+ return failure
+ if self!assert-no-cycle($project) == failure;
+ return failure
+ if self!fetch-all-dependencies($project) == failure;
return failure
if self!build-helper($project) == failure;
}
@@ -162,9 +177,13 @@ class App::Pls::Core {
method test(*@projects) {
for @projects -> $project {
- my %*seen-projects;
return failure
if self!fetch-helper($project) == failure;
+ my %*seen-projects;
+ return failure
+ if self!assert-no-cycle($project) == failure;
+ return failure
+ if self!fetch-all-dependencies($project) == failure;
return failure
if self!build-helper($project) != success;
return failure
@@ -189,9 +208,11 @@ class App::Pls::Core {
method install(*@projects, Bool :$force, Bool :$skip-test) {
my $needed-force = False;
for @projects -> $project {
- my %*seen-projects;
return failure
if self!fetch-helper($project) == failure;
+ my %*seen-projects;
+ return failure
+ if self!assert-no-cycle($project) == failure;
# RAKUDO: an unspecified $force should be False, is Any
my $build-result = self!build-helper($project, :force(?$force),
:skip-test(?$skip-test));
View
@@ -30,7 +30,7 @@ my $core = App::Pls::Core.new(
:fetcher(Mock::Fetcher.new()),
);
-plan 24;
+plan 14;
given $core {
# [T] Fetch a project: Succeed.
@@ -42,31 +42,12 @@ given $core {
is .fetch(<will-fail>), failure, "Fetch a project: Fail";
is .state-of('will-fail'), 'absent', "State after: 'absent'";
- # [T] Fetch a project with dependencies: Fetch dependencies too.
+ # [T] Fetch a project with dependencies: don't fetch dependencies too.
for <A B C D> -> $dep {
is .state-of($dep), 'absent', "State before of $dep: 'absent'";
}
is .fetch(<has-deps>), success, "Fetch project's dependencies, too";
for <A B C D> -> $dep {
- is .state-of($dep), 'fetched', "State after of $dep: 'fetched'";
+ is .state-of($dep), 'absent', "State after of $dep: 'fetched'";
}
-
- # [T] Fetch a project with circular dependencies: Fail.
- is .fetch(<circ-deps>), failure, "Fetch a project with circ deps: fail";
- is .state-of('circ-deps'), 'absent', "State after of circ-deps: 'absent'";
- is .state-of('E'), 'absent', "State after of E: 'absent'";
-
- # [T] Fetch a project whose direct dependency fails: Fail.
- is .fetch(<dirdep-fails>), failure, "Fail on direct dependency failure";
- is .state-of('dirdep-fails'), 'absent',
- "State after of dirdep-fails: 'absent'";
- is .state-of('will-fail'), 'absent', "State after of will-fail: 'absent'";
-
- # [T] Fetch a project whose indirect dependency fails: Fail.
- is .fetch(<indir-fails>), failure, "Fail on indirect dependency failure";
- is .state-of('indir-fails'), 'absent',
- "State after of indir-fails: 'absent'";
- is .state-of('dirdep-fails'), 'absent',
- "State after of dirdep-fails: 'absent'";
- is .state-of('will-fail'), 'absent', "State after of will-fail: 'absent'";
}

0 comments on commit 7522692

Please sign in to comment.