File Coverage

blib/lib/Verby.pm
Criterion Covered Total %
statement 6 6 100.0
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 8 8 100.0


line stmt bran cond sub pod time code
1              
2             package Verby;
3              
4 1     1   54273 use strict;
  1         3  
  1         32  
5 1     1   5 use warnings;
  1         1  
  1         53  
6              
7             our $VERSION = "0.05";
8              
9             __PACKAGE__
10              
11             __END__
12              
13             =head1 NAME
14              
15             Verby - A framework for compositing and sequencing steps of execution.
16              
17             =head1 SYNOPSIS
18              
19             use Verby::Dispatcher;
20             use Verby::Step::Closure qw/step/;
21              
22             my $d = Verby::Dispatcher->new;
23              
24             my $s = step "Verby::Action::Foo";
25             my $other = step "Verby::Action::Bar";
26              
27             $s->depends($other);
28              
29             $d->add_step($s);
30              
31             $d->do_all; # first $other, then $s
32              
33             =head1 DESCRIPTION
34              
35             L<Verby> was originally written to implement the backend of an installer.
36              
37             An installer conceptually has two inputs, which are combined to get the job
38             done.
39              
40             The first is the user's configuration (regardless of how it's provided) - the
41             parameters to influence the installation, and the second is the recipe for the
42             actual execution of the installation, a sort of template if you will, that the
43             configuration fills in.
44              
45             L<Verby> defines the two concepts (not only for installers), and provides some
46             useful code to get them working.
47              
48             In spirit it's very similar to C<Makefile>s, except that the data involved are
49             mentally closer to Perl than they are to sh(1).
50              
51             =head1 CONFIGURATION
52              
53             This core concept discusses the way that user inputs are handed down to the
54             execution sequence.
55              
56             =head1 Config Sources
57              
58             A config source is basically a key to value mapping.
59              
60             It's an object where you ask
61              
62             $obj->key;
63              
64             and you get the value.
65              
66             If the object makes a query to the user, like displaying a prompt for a certain
67             key, then the answer should be cached, as each key will probably be asked for
68             about 3-5 times for each step.
69              
70             =head1 Config Hub
71              
72             A config hub is a union of several config sources. For example, a typical
73             command line app would have three config sources:
74              
75             my $args = Verby::Config::Source::ARGV->new; # foo --key=value
76             my $config_file = Verby::Config::Source::XML->new("config.xml");
77             my $conifg_prompt = Verby::Config::Source::Prompt; # last resort
78              
79             my $config_hub = Verby::Config::Data->new($args, $config_file, $config_prompt);
80              
81             $config_hub->key;
82              
83             The config hub is sort of like an aggregate config source. It will ask it's
84             parents for the key.
85              
86             The key ordering is symmetric (like role composition order), that is if two
87             parents both contain the key it's as if there is no match, and a warning is
88             emitted.
89              
90             =head1 Context
91              
92             A context is like a lexical config, for each step.
93              
94             my $context = $config_hub->derive;
95              
96             It is mutable:
97              
98             $context->key("foo"); # set it
99              
100             It can be further derived
101              
102             my $subcontext = $context->derive;
103             $subcontext->key; # "foo"
104              
105             It masks:
106              
107             $subcontext->key("bar");
108             $subcontext->key; # "bar"
109             $context->key; # still "foo";
110              
111             And it can re-export:
112              
113             $subcontext->export("key");
114             $context->key; # "bar" instead of "foo"
115              
116             ...as long as it's parent is mutable:
117              
118             $context->export("key"); # fatal error
119             # because $config_hub is not mutable
120              
121             It also provides a magic field:
122              
123             my $l = $c->logger;
124              
125             See L<MooseX::LogDispatch>. If a logger is in a parent of the context it will
126             be returned instead.
127              
128             =head1 EXECUTION
129              
130             The L<Verby> execution model is much like a C<Makefile>'s.
131              
132             There is a tree of dependant steps, which will all be executed when necessary
133             and possible.
134              
135             By adding a step to a dispatcher, all it's dependencies are traversed and added
136             too.
137              
138             Any step that is inserted is immediately asked whether it C<is_satisfied>.
139              
140             Subsequently L<Verby::Dispatcher/do_all> is called. Dependencies are resolved,
141             and any step that has no dependencies, and has not yet claimed it's satisfied
142             is executed.
143              
144             Every step gets it's own context to play around in. This context persists
145             between invocations of all the methods.
146              
147             A step which C<provides_cxt> is a special case: Instead of deriving the global
148             context generated for the whole run, an intermediate context is derived first,
149             and then that step's context is derived from the intermediate one. Any step
150             which depends on this step, will have it's context derived from the
151             intermediate context too.
152              
153             =head1 STYLE GUIDE
154              
155             When writing actions to back steps up make sure they will fail properly. For
156             example, missing fields in C<verify> might be due to the fact that some step
157             did not export a necessary field yet. In this case C<verify> should just return
158             false, and will be asked again in due time.
159              
160             An error, on the other hand, should be fatal. L<Verby> uses
161             L<MooseX::LogDispatch> to do this.
162              
163             Actions should be short and sweet, doing as little as possible. Remember that a
164             step being a delegator for actions is not limited to using only one action, so
165             if you need to combine procedures, still try to refactor them.
166              
167             Long running steps, especially ones which drive external processes, like ones
168             using L<Verby::Action::Run> should be asynchroneous. This allows
169             non-interdependant steps to be executed in parallel.
170              
171             Actions should minimize partial side effects. Transactional behavior is desired
172             for the incremental process to be robust. Ideally the C<do> part of an action
173             will undo previous runs, and the C<verify> part will only be true if the side
174             effect is marked as consistent.
175              
176             Context fields should be exported from the verification stage, because
177             sometimes a step will not be executed. If execution is necessary to figure out
178             a field that may be exported, then verification should be false.
179              
180             =head1 BUGS
181              
182             None that we are aware of. Of course, if you find a bug, let us know, and we will be sure to fix it.
183              
184             =head1 CODE COVERAGE
185              
186             We use B<Devel::Cover> to test the code coverage of the tests, below is the B<Devel::Cover> report on this module's test suite.
187              
188             =head1 SEE ALSO
189              
190             =head1 AUTHOR
191              
192             Yuval Kogman, E<lt>nothingmuch@woobling.orgE<gt>
193             stevan little, E<lt>stevan@iinteractive.comE<gt>
194              
195             =head1 COPYRIGHT AND LICENSE
196              
197             Copyright 2005-2008 by Infinity Interactive, Inc.
198              
199             L<http://www.iinteractive.com>
200              
201             This library is free software; you can redistribute it and/or modify
202             it under the same terms as Perl itself.
203              
204             =cut