File Coverage

blib/lib/Getopt/Chain.pm
Criterion Covered Total %
statement 11 13 84.6
branch 1 2 50.0
condition n/a
subroutine 5 5 100.0
pod n/a
total 17 20 85.0


line stmt bran cond sub pod time code
1             package Getopt::Chain;
2             BEGIN {
3 5     5   470293 $Getopt::Chain::VERSION = '0.017';
4             }
5             # ABSTRACT: Command-line processing like svn and git
6              
7 5     5   47 use warnings;
  5         9  
  5         124  
8 5     5   34 use strict;
  5         10  
  5         201  
9              
10 5 50   5   26 use constant DEBUG => $ENV{GOC_TRACE} ? 1 : 0;
  5         10  
  5         443  
11             our $DEBUG = DEBUG;
12              
13              
14 5     5   8906 use Moose;
  0            
  0            
15             use Getopt::Chain::Carp;
16              
17             use Getopt::Chain::Builder;
18             use Getopt::Chain::Context;
19              
20             has builder => qw/is ro lazy_build 1/, handles => [qw/ dispatcher /];
21             sub _build_builder {
22             require Getopt::Chain::Builder;
23             return Getopt::Chain::Builder->new;
24             }
25              
26             has context_from => qw/is ro isa Str|CodeRef lazy_build 1/;
27             sub _build_context_from {
28             return 'Getopt::Chain::Context';
29             }
30              
31             sub process {
32             if (! ref $_[0] && $_[0] && $_[0] eq 'Getopt::Chain') {
33             shift;
34             require Getopt::Chain::v005;
35             carp "Deprecated: Use Getopt::Chain::v005->process( ... ) to avoid this warning (this method will be removed in a future version)";
36             return Getopt::Chain::v005->process( @_ );
37             }
38             }
39              
40             sub run {
41             if (! ref $_[0] ) {
42             croak "Can't call run on the package; use ->new first";
43             }
44             my $self = shift;
45             my $arguments = shift;
46              
47             $arguments = [ @ARGV ] unless $arguments;
48              
49             my $context = $self->new_context( dispatcher => $self->dispatcher, arguments => $arguments );
50             $context->run;
51             return $context->options;
52             }
53              
54             sub new_context {
55             my $self = shift;
56              
57             my $context_from = $self->context_from;
58             if (! ref $context_from) {
59             return $context_from->new( @_ );
60             }
61             else {
62             croak "Don't understand context source \"$context_from\"";
63             }
64             }
65              
66             use MooseX::MakeImmutable;
67             MooseX::MakeImmutable->lock_down;
68              
69              
70             1; # End of Getopt::Chain
71              
72             __END__
73             =pod
74              
75             =head1 NAME
76              
77             Getopt::Chain - Command-line processing like svn and git
78              
79             =head1 VERSION
80              
81             version 0.017
82              
83             =head1 DESCRIPTION
84              
85             Getopt::Chain can be used to provide C<svn(1)>- and C<git(1)>-style option and command processing. Any option specification
86             covered by L<Getopt::Long> is fair game.
87              
88             This is a new version of Getopt::Chain that uses L<Path::Dispatcher>
89              
90             CAVEAT 1: This is pretty beta, so the sugar/interface above WILL be tweaked
91              
92             CAVEAT 2: Unfortunately, Getopt::Long slurps up the entire arguments array at once. Usually, this isn't a problem (as Getopt::Chain uses
93             pass_through). However, if a subcommand has an option with the same name or alias as an option for a parent, then that option won't be available
94             for the subcommand. For example:
95              
96             ./script --verbose --revision 36 edit --revision 48 --file xyzzy.c
97             # Getopt::Chain will not associate the second --revision with "edit"
98              
99             So, for now, try to use distinct option names/aliases :)
100              
101             DEBUG: You can get some extra information about what Getopt::Chain is doing by setting the environment variable C<GOC_TRACE> to 1
102              
103             =head1 SYNPOSIS
104              
105             package My::Command;
106              
107             use Getopt::Chain::Declare;
108              
109             start [qw/ verbose|v /]; # These are "global"
110             # my-command --verbose initialize ...
111              
112             # my-command ? initialize ... --> my-command help initialize ...
113             rewrite qr/^\?(.*)/ => sub { "help ".($1||'') };
114              
115             # NOTE: Rewriting applies to the command sequence, NOT options
116              
117             # my-command about ... --> my-command help about
118             rewrite [ ['about', 'copying'] ] => sub { "help $1" };
119              
120             # my-command initialize --dir=...
121             on initialize => [qw/ dir|d=s /], sub {
122             my $context = shift;
123              
124             my $dir = $context->option( 'dir' )
125              
126             # Do initialize stuff with $dir
127             };
128              
129             # my-command help
130             on help => undef, sub {
131             my $context = shift;
132              
133             # Do help stuff ...
134             # First argument is undef because help
135             # doesn't take any options
136             };
137              
138             under help => sub {
139              
140             # my-command help create
141             # my-command help initialize
142             on [ [ qw/create initialize/ ] ] => undef, sub {
143             my $context = shift;
144              
145             # Do help for create/initialize
146             # Both: "help create" and "help initialize" go here
147             };
148              
149             # my-command help about
150             on 'about' => undef, sub {
151             my $context = shift;
152              
153             # Help for about...
154             };
155              
156             # my-command help copying
157             on 'copying' => undef, sub {
158             my $context = shift;
159              
160             # Help for copying...
161             };
162              
163             # my-command help ...
164             on qr/^(\S+)$/ => undef, sub {
165             my $context = shift;
166             my $topic = $1;
167              
168             # Catch-all for anything not fitting into the above...
169              
170             warn "I don't know about \"$topic\"\n"
171             };
172             };
173              
174             # ... elsewhere ...
175              
176             My::Command->new->run( [ @arguments ] )
177             My::Command->new->run # Just run with @ARGV
178              
179             =head1 LEGACY
180              
181             The old-style, non L<Path::Dispatcher> version is still available at L<Getopt::Chain::v005>
182              
183             =head1 SEE ALSO
184              
185             L<Getopt::Long>
186              
187             L<App::Cmd>
188              
189             L<MooseX::App::Cmd>
190              
191             =head1 ACKNOWLEDGEMENTS
192              
193             Sartak for L<Path::Dispatcher>
194              
195             obra for inspiration on the CLI (via Prophet & Sd: L<http://syncwith.us/>)
196              
197             =head1 AUTHOR
198              
199             Robert Krimen <robertkrimen@gmail.com>
200              
201             =head1 COPYRIGHT AND LICENSE
202              
203             This software is copyright (c) 2011 by Robert Krimen.
204              
205             This is free software; you can redistribute it and/or modify it under
206             the same terms as the Perl 5 programming language system itself.
207              
208             =cut
209