File Coverage

blib/lib/Bot/Training.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package Bot::Training;
2             our $AUTHORITY = 'cpan:AVAR';
3             $Bot::Training::VERSION = '0.06';
4 1     1   1476 use 5.010;
  1         2  
  1         35  
5 1     1   457 use autodie qw(open close);
  1         14174  
  1         5  
6 1     1   938 use Class::Load;
  1         26916  
  1         52  
7 1     1   208 use Moose;
  0            
  0            
8             use Module::Pluggable (
9             search_path => [ 'Bot::Training' ],
10             except => [ 'Bot::Training::Plugin' ],
11             );
12             use List::Util qw< first >;
13             use namespace::clean -except => [ qw< meta plugins > ];
14              
15             with 'MooseX::Getopt::Dashes';
16              
17             has help => (
18             traits => [ qw/ Getopt / ],
19             cmd_aliases => 'h',
20             cmd_flag => 'help',
21             isa => 'Bool',
22             is => 'ro',
23             default => 0,
24             documentation => 'This help message',
25             );
26              
27             has _go_version => (
28             traits => [ qw/ Getopt / ],
29             cmd_aliases => 'v',
30             cmd_flag => 'version',
31             documentation => 'Print version and exit',
32             isa => 'Bool',
33             is => 'ro',
34             );
35              
36             has _go_list => (
37             traits => [ qw/ Getopt / ],
38             cmd_aliases => 'l',
39             cmd_flag => 'list',
40             documentation => 'List the known Bot::Training files. Install Task::Bot::Training to get them all',
41             isa => 'Bool',
42             is => 'ro',
43             );
44              
45             has _go_file => (
46             traits => [ qw/ Getopt / ],
47             cmd_aliases => 'f',
48             cmd_flag => 'file',
49             documentation => 'The file to retrieve. Matched case-insensitively against Bot::Training plugins',
50             isa => 'Str',
51             is => 'ro',
52             );
53              
54             sub _new_class {
55             my ($self, $class) = @_;
56              
57             my $pkg;
58             if ($class =~ m[^\+(?<custom_plugin>.+)$]) {
59             $pkg = $+{custom_plugin};
60             } else {
61             # Be fuzzy about includes, e.g. Training::Test, Test or test is OK
62             $pkg = first { / : $class /ix }
63             sort { length $a <=> length $b }
64             $self->plugins;
65              
66             unless ($pkg) {
67             local $" = ', ';
68             my @plugins = $self->plugins;
69             die "Couldn't find a class name matching '$class' in plugins '@plugins'";
70             }
71             }
72              
73             Class::Load::load_class($pkg);
74              
75             return $pkg->new;
76             }
77              
78             sub file {
79             my ($self, $fuzzy) = @_;
80              
81             return $self->_new_class($fuzzy);
82              
83             }
84              
85             sub run {
86             my ($self) = @_;
87              
88             if ($self->_go_version) {
89             # Munging strictness because we don't have a version from a
90             # Git checkout. Dist::Zilla provides it.
91             no strict 'vars';
92             my $version = $VERSION // 'dev-git';
93              
94             say "bot-training $version";
95             return;
96             }
97              
98             if ($self->_go_list) {
99             my @plugins = $self->plugins;
100             if (@plugins) {
101             say for @plugins;
102             } else {
103             say "No plugins loaded. Install Task::Bot::Training";
104             return 1;
105             }
106             }
107            
108             if ($self->_go_file) {
109             my $trn = $self->file( $self->_go_file );;
110             open my $fh, "<", $trn->file;
111             print while <$fh>;
112             close $fh;
113             }
114              
115             }
116              
117             # --i--do-not-exist
118             sub _getopt_spec_exception { goto &_getopt_full_usage }
119              
120             # --help
121             sub print_usage_text {
122             my ($self, $usage, $plain_str) = @_;
123              
124             # If called from _getopt_spec_exception we get "Unknown option: foo"
125             my $warning = ref $usage eq 'ARRAY' ? $usage->[0] : undef;
126              
127             my ($use, $options) = do {
128             # $plain_str under _getopt_spec_exception
129             my $out = $plain_str // $usage->text;
130              
131             # The default getopt order sucks, use reverse sort order
132             my @out = split /^/, $out;
133             chomp @out;
134             my $opt = join "\n", sort { $b cmp $a } @out[1 .. $#out];
135             ($out[0], $opt);
136             };
137             my $synopsis = do {
138             require Pod::Usage;
139             my $out;
140             open my $fh, '>', \$out;
141              
142             no warnings 'once';
143              
144             my $hailo = File::Spec->catfile($Hailo::Command::HERE_MOMMY, 'hailo');
145             # Try not to fail on Win32 or other odd systems which might have hailo.pl not hailo
146             $hailo = ((glob("$hailo*"))[0]) unless -f $hailo;
147             Pod::Usage::pod2usage(
148             -input => $hailo,
149             -sections => 'SYNOPSIS',
150             -output => $fh,
151             -exitval => 'noexit',
152             );
153             close $fh;
154              
155             $out =~ s/\n+$//s;
156             $out =~ s/^Usage:/examples:/;
157              
158             $out;
159             };
160              
161             # Unknown option provided
162             print $warning if $warning;
163              
164             print <<"USAGE";
165             $use
166             $options
167             USAGE
168              
169             say "\n", $synopsis;
170              
171             exit 1;
172             }
173              
174             __PACKAGE__->meta->make_immutable;
175              
176             =encoding utf8
177              
178             =head1 NAME
179              
180             Bot::Training - Plain text training material for bots like L<Hailo> and L<AI::MegaHAL>
181              
182             =head1 SYNOPSIS
183              
184             use Bot::Training;
185             use File::Slurp qw< slurp >;
186              
187             my $bt = Bot::Training->new;
188              
189             # Plugins I know about. Install Task::Bot::Training for more:
190             my @plugins = $bt->plugins
191              
192             # Get the plugin object of a .trn file (which is just a plain text
193             # file). These all work just as well:
194             my $hal = $bt->file('megahal');
195             my $hal = $bt->file('MegaHAL');
196             my $hal = $bt->file('Bot::Training::MegaHAL');
197              
198             # Get all lines in the file with File::Slurp:
199             my @test = split /\n/, slurp($hal->file);
200              
201             =head1 DESCRIPTION
202              
203             Markov bots like L<Hailo> and L<AI::MegaHAL> are fun. But to get them
204             working you either need to train them on existing training material or
205             make your own.
206              
207             This module provides a pluggable way to install already existing
208             training files via the CPAN. It also comes with a command-line
209             interface called C<bot-training>.
210              
211             =head1 AUTHOR
212              
213             E<AElig>var ArnfjE<ouml>rE<eth> Bjarmason <avar@cpan.org>
214              
215             =head1 LICENSE AND COPYRIGHT
216              
217             Copyright 2010 E<AElig>var ArnfjE<ouml>rE<eth> Bjarmason <avar@cpan.org>
218              
219             This program is free software, you can redistribute it and/or modify
220             it under the same terms as Perl itself.
221              
222             =cut