1package TAP::Parser::SourceHandler::File; 2 3use strict; 4use warnings; 5 6use TAP::Parser::IteratorFactory (); 7use TAP::Parser::Iterator::Stream (); 8 9use base 'TAP::Parser::SourceHandler'; 10 11TAP::Parser::IteratorFactory->register_handler(__PACKAGE__); 12 13=head1 NAME 14 15TAP::Parser::SourceHandler::File - Stream TAP from a text file. 16 17=head1 VERSION 18 19Version 3.48 20 21=cut 22 23our $VERSION = '3.48'; 24 25=head1 SYNOPSIS 26 27 use TAP::Parser::Source; 28 use TAP::Parser::SourceHandler::File; 29 30 my $source = TAP::Parser::Source->new->raw( \'file.tap' ); 31 $source->assemble_meta; 32 33 my $class = 'TAP::Parser::SourceHandler::File'; 34 my $vote = $class->can_handle( $source ); 35 my $iter = $class->make_iterator( $source ); 36 37=head1 DESCRIPTION 38 39This is a I<raw TAP stored in a file> L<TAP::Parser::SourceHandler> - it has 2 jobs: 40 411. Figure out if the I<raw> source it's given is a file containing raw TAP 42output. See L<TAP::Parser::IteratorFactory> for more details. 43 442. Takes raw TAP from the text file given, and converts into an iterator. 45 46Unless you're writing a plugin or subclassing L<TAP::Parser>, you probably 47won't need to use this module directly. 48 49=head1 METHODS 50 51=head2 Class Methods 52 53=head3 C<can_handle> 54 55 my $vote = $class->can_handle( $source ); 56 57Only votes if $source looks like a regular file. Casts the following votes: 58 59 0.9 if it's a .tap file 60 0.9 if it has an extension matching any given in user config. 61 62=cut 63 64sub can_handle { 65 my ( $class, $src ) = @_; 66 my $meta = $src->meta; 67 my $config = $src->config_for($class); 68 69 return 0 unless $meta->{is_file}; 70 my $file = $meta->{file}; 71 return 0.9 if $file->{lc_ext} eq '.tap'; 72 73 if ( my $exts = $config->{extensions} ) { 74 my @exts = ref $exts eq 'ARRAY' ? @$exts : $exts; 75 return 0.9 if grep { lc($_) eq $file->{lc_ext} } @exts; 76 } 77 78 return 0; 79} 80 81=head3 C<make_iterator> 82 83 my $iterator = $class->make_iterator( $source ); 84 85Returns a new L<TAP::Parser::Iterator::Stream> for the source. C<croak>s 86on error. 87 88=cut 89 90sub make_iterator { 91 my ( $class, $source ) = @_; 92 93 $class->_croak('$source->raw must be a scalar ref') 94 unless $source->meta->{is_scalar}; 95 96 my $file = ${ $source->raw }; 97 my $fh; 98 open( $fh, '<', $file ) 99 or $class->_croak("error opening TAP source file '$file': $!"); 100 return $class->iterator_class->new($fh); 101} 102 103=head3 C<iterator_class> 104 105The class of iterator to use, override if you're sub-classing. Defaults 106to L<TAP::Parser::Iterator::Stream>. 107 108=cut 109 110use constant iterator_class => 'TAP::Parser::Iterator::Stream'; 111 1121; 113 114__END__ 115 116=head1 CONFIGURATION 117 118 { 119 extensions => [ @case_insensitive_exts_to_match ] 120 } 121 122=head1 SUBCLASSING 123 124Please see L<TAP::Parser/SUBCLASSING> for a subclassing overview. 125 126=head1 SEE ALSO 127 128L<TAP::Object>, 129L<TAP::Parser>, 130L<TAP::Parser::SourceHandler>, 131L<TAP::Parser::SourceHandler::Executable>, 132L<TAP::Parser::SourceHandler::Perl>, 133L<TAP::Parser::SourceHandler::Handle>, 134L<TAP::Parser::SourceHandler::RawTAP> 135 136=cut 137