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.05';
4 1     1   1610 use 5.010;
  1         3  
  1         35  
5 1     1   448 use autodie qw(open close);
  1         17554  
  1         6  
6 1     1   860 use Class::Load;
  1         28986  
  1         43  
7 1     1   201 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 _getopt_full_usage {
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             chomp(my @out = split /^/, $out);
133             my $opt = join "\n", sort { $b cmp $a } @out[1 .. $#out];
134             ($out[0], $opt);
135             };
136             my $synopsis = do {
137             require Pod::Usage;
138             my $out;
139             open my $fh, '>', \$out;
140              
141             no warnings 'once';
142              
143             my $hailo = File::Spec->catfile($Hailo::Command::HERE_MOMMY, 'hailo');
144             # Try not to fail on Win32 or other odd systems which might have hailo.pl not hailo
145             $hailo = ((glob("$hailo*"))[0]) unless -f $hailo;
146             Pod::Usage::pod2usage(
147             -input => $hailo,
148             -sections => 'SYNOPSIS',
149             -output => $fh,
150             -exitval => 'noexit',
151             );
152             close $fh;
153              
154             $out =~ s/\n+$//s;
155             $out =~ s/^Usage:/examples:/;
156              
157             $out;
158             };
159              
160             # Unknown option provided
161             print $warning if $warning;
162              
163             print <<"USAGE";
164             $use
165             $options
166             USAGE
167              
168             say "\n", $synopsis;
169              
170             exit 1;
171             }
172              
173             __PACKAGE__->meta->make_immutable;
174              
175             =encoding utf8
176              
177             =head1 NAME
178              
179             Bot::Training - Plain text training material for bots like L<Hailo> and L<AI::MegaHAL>
180              
181             =head1 SYNOPSIS
182              
183             use Bot::Training;
184             use File::Slurp qw< slurp >;
185              
186             my $bt = Bot::Training->new;
187              
188             # Plugins I know about. Install Task::Bot::Training for more:
189             my @plugins = $bt->plugins
190              
191             # Get the plugin object of a .trn file (which is just a plain text
192             # file). These all work just as well:
193             my $hal = $bt->file('megahal');
194             my $hal = $bt->file('MegaHAL');
195             my $hal = $bt->file('Bot::Training::MegaHAL');
196              
197             # Get all lines in the file with File::Slurp:
198             my @test = split /\n/, slurp($hal->file);
199              
200             =head1 DESCRIPTION
201              
202             Markov bots like L<Hailo> and L<AI::MegaHAL> are fun. But to get them
203             working you either need to train them on existing training material or
204             make your own.
205              
206             This module provides a pluggable way to install already existing
207             training files via the CPAN. It also comes with a command-line
208             interface called C<bot-training>.
209              
210             =head1 AUTHOR
211              
212             E<AElig>var ArnfjE<ouml>rE<eth> Bjarmason <avar@cpan.org>
213              
214             =head1 LICENSE AND COPYRIGHT
215              
216             Copyright 2010 E<AElig>var ArnfjE<ouml>rE<eth> Bjarmason <avar@cpan.org>
217              
218             This program is free software, you can redistribute it and/or modify
219             it under the same terms as Perl itself.
220              
221             =cut