move actions to being held by fact objects
Matt S Trout [Tue, 11 Feb 2014 19:54:12 +0000 (19:54 +0000)]
lib/DX/Op/ProposeAction.pm
lib/DX/RefSet.pm [new file with mode: 0644]
lib/DX/Result.pm
lib/DX/Role/Action.pm [new file with mode: 0644]
lib/DX/Role/Fact.pm [new file with mode: 0644]
lib/DX/Role/Ref.pm [new file with mode: 0644]
lib/DX/State.pm
lib/DX/Var.pm
t/dot_ssh.t

index 2249496..b1aa7f3 100644 (file)
@@ -22,13 +22,9 @@ sub run {
   my $action = $self->builder->(map $state->resolve_value($_), @vars)
                     ->but(dependencies => \@deps);
   my ($fact_type, $value) = $action->expected_effect;
-  my $id = $vars[0]->id;
-  my $var = $state->by_id->{$id}->with_action($action);
-  my $fact_set = $state->facts->{$fact_type}->with_value($value);
-  $state->but(
-            by_id => { %{$state->by_id}, $id => $var },
-            facts => { %{$state->facts}, $fact_type => $fact_set },
-          )
+  my $final_value = $value->but(required_action => $action);
+  my $fact_set = $state->facts->{$fact_type}->with_value($final_value);
+  $state->but(facts => { %{$state->facts}, $fact_type => $fact_set })
         ->then($self->next);
 }
 
diff --git a/lib/DX/RefSet.pm b/lib/DX/RefSet.pm
new file mode 100644 (file)
index 0000000..58827cb
--- /dev/null
@@ -0,0 +1,19 @@
+package DX::RefSet;
+
+use DX::FactRef;
+use DX::ArrayStream;
+use Moo;
+
+has target => (is => 'ro', required => 1);
+
+has names => (is => 'ro', required => 1);
+
+sub to_stream {
+  my ($self) = @_;
+  return DX::ArrayStream->from_array(
+    map DX::FactRef->new(fact_type => $self->target, fact_id => $_),
+      @{$self->names}
+  );
+}
+
+1;
index 85d6774..ddfb626 100644 (file)
@@ -1,5 +1,6 @@
 package DX::Result;
 
+use Safe::Isa;
 use Moo;
 
 has _state => (is => 'ro', required => 1, init_arg => 'state');
@@ -10,8 +11,13 @@ sub var_names {
 
 sub actions {
   my ($self) = @_;
+  my $state = $self->_state;
   my $by_id = $self->_state->by_id;
-  return map $_->action, grep $_->has_action, values %$by_id;
+  return map $_->required_action,
+           grep $_->has_required_action,
+             grep $_->$_does('DX::Role::Fact'),
+               map $state->resolve_value($_),
+                 values %$by_id;
 }
 
 sub independent_actions {
diff --git a/lib/DX/Role/Action.pm b/lib/DX/Role/Action.pm
new file mode 100644 (file)
index 0000000..113dd44
--- /dev/null
@@ -0,0 +1,22 @@
+package DX::Role::Action;
+
+use Moo::Role;
+
+has dependencies => (is => 'ro', default => sub { [] });
+
+has was_run => (is => 'rw');
+
+requires 'expected_effect';
+requires '_do_run';
+
+sub but { my ($self, @but) = @_; ref($self)->new(%$self, @but); }
+
+sub run {
+  my ($self) = @_;
+  die "Can't run, was already run" if $self->was_run;
+  my @res = $self->_do_run;
+  $self->was_run(1);
+  return @res;
+}
+
+1;
diff --git a/lib/DX/Role/Fact.pm b/lib/DX/Role/Fact.pm
new file mode 100644 (file)
index 0000000..33a8287
--- /dev/null
@@ -0,0 +1,9 @@
+package DX::Role::Fact;
+
+use Moo::Role;
+
+has required_action => (is => 'ro', predicate => 1);
+
+sub but { ref($_[0])->new(%{$_[0]}, @_[1..$#_]) }
+
+1;
diff --git a/lib/DX/Role/Ref.pm b/lib/DX/Role/Ref.pm
new file mode 100644 (file)
index 0000000..3e4f8f2
--- /dev/null
@@ -0,0 +1,7 @@
+package DX::Role::Ref;
+
+use Moo::Role;
+
+requires 'resolve';
+
+1;
index 1f84991..2f0e2b0 100644 (file)
@@ -187,7 +187,9 @@ sub action_dependencies {
   my @queue = @ids;
   while (my $id = shift @queue) {
     $seen{$id}++;
-    push @found, $id if $by_id->{$id}->has_action;
+    my $value = $self->resolve_value($by_id->{$id});
+    push @found, $id if $value->$_does('DX::Role::Fact')
+                        and $value->has_required_action;
     push @queue, grep !$seen{$_}, keys %{$deps->{$id}};
   }
   return @found;
index f2c11dd..3904186 100644 (file)
@@ -22,8 +22,6 @@ has bound_value => (is => 'lazy', predicate => 1, clearer => 1, builder => sub {
   return;
 });
 
-has action => (is => 'ro', predicate => 1);
-
 sub is_bound {
   my ($self) = @_;
   $self->has_bound_value || $self->has_bound_stream || $self->has_root_set;
@@ -39,11 +37,6 @@ sub with_value {
   $self->new(%$self, bound_value => $stream);
 }
 
-sub with_action {
-  my ($self, $action) = @_;
-  $self->new(%$self, action => $action);
-}
-
 sub with_root_set {
   my ($self, $set) = @_;
   $self->new(%$self, root_set => $set);
index b06771c..1ac8b04 100644 (file)
@@ -12,6 +12,8 @@ use Test::Exception;
 
   use Moo;
 
+  with 'DX::Role::Fact';
+
   has path => (is => 'ro', required => 1);
   has info => (is => 'ro', predicate => 1);
 
@@ -19,6 +21,8 @@ use Test::Exception;
 
   use Moo;
 
+  with 'DX::Role::Fact';
+
   has is_directory => (is => 'ro', default => 0);
   has is_file => (is => 'ro', default => 0);
   has mode => (is => 'ro', required => 1);