File Coverage

blib/lib/App/RL/Command/span.pm
Criterion Covered Total %
statement 74 80 92.5
branch 22 28 78.5
condition n/a
subroutine 11 11 100.0
pod 6 6 100.0
total 113 125 90.4


line stmt bran cond sub pod time code
1             package App::RL::Command::span;
2 15     15   15023 use strict;
  15         44  
  15         565  
3 15     15   95 use warnings;
  15         38  
  15         529  
4 15     15   92 use autodie;
  15         40  
  15         128  
5              
6 15     15   98680 use App::RL -command;
  15         43  
  15         284  
7 15     15   7777 use App::RL::Common;
  15         85  
  15         22514  
8              
9             sub abstract {
10 2     2 1 95 return 'operate spans in a YAML file';
11             }
12              
13             sub opt_spec {
14             return (
15 8     8 1 100 [ "outfile|o=s", "output filename. [stdout] for screen" ],
16             [ "op=s", "operations: cover, holes, trim, pad, excise or fill", { default => "cover" } ],
17             [ "number|n=i", "apply this number to trim, pad, excise or fill", { default => 0 } ],
18             [ "remove|r", "remove 'chr0' from chromosome names" ],
19             [ "mk", "YAML file contains multiple sets of runlists" ],
20             { show_defaults => 1, }
21             );
22             }
23              
24             sub usage_desc {
25 8     8 1 77510 return "runlist span [options] ";
26             }
27              
28             sub description {
29 1     1 1 1510 my $desc;
30 1         6 $desc .= ucfirst(abstract) . ".\n";
31 1         3 $desc .= <<'MARKDOWN';
32              
33             List of operations:
34              
35             * cover: a single span from min to max
36             * holes: all the holes in runlist
37             * trim: remove N integers from each end of each span of runlist
38             * pad: add N integers from each end of each span of runlist
39             * excise: remove all spans smaller than N
40             * fill: fill in all holes smaller than N
41              
42             MARKDOWN
43              
44 1         3 return $desc;
45             }
46              
47             sub validate_args {
48 7     7 1 13643 my ( $self, $opt, $args ) = @_;
49              
50 7 100       19 if ( @{$args} != 1 ) {
  7         35  
51 1         3 my $message = "This command need one input file.\n\tIt found";
52 1         2 $message .= sprintf " [%s]", $_ for @{$args};
  1         4  
53 1         4 $message .= ".\n";
54 1         11 $self->usage_error($message);
55             }
56 6         13 for ( @{$args} ) {
  6         22  
57 6 50       24 next if lc $_ eq "stdin";
58 6 100       43 if ( !Path::Tiny::path($_)->is_file ) {
59 1         134 $self->usage_error("The input file [$_] doesn't exist.");
60             }
61             }
62              
63 5 100       610 if ( $opt->{op} =~ /^cover/i ) {
    100          
    100          
    50          
    100          
    50          
64 1         3 $opt->{op} = 'cover';
65             }
66             elsif ( $opt->{op} =~ /^hole/i ) {
67 1         5 $opt->{op} = 'holes';
68             }
69             elsif ( $opt->{op} =~ /^trim/i ) {
70 1         9 $opt->{op} = 'trim';
71             }
72             elsif ( $opt->{op} =~ /^pad/i ) {
73 0         0 $opt->{op} = 'pad';
74             }
75             elsif ( $opt->{op} =~ /^excise/i ) {
76 1         4 $opt->{op} = 'excise';
77             }
78             elsif ( $opt->{op} =~ /^fill/i ) {
79 1         4 $opt->{op} = 'fill';
80             }
81             else {
82 0         0 Carp::confess "[@{[$opt->{op}]}] is invalid\n";
  0         0  
83             }
84              
85 5 50       44 if ( !exists $opt->{outfile} ) {
86 0         0 $opt->{outfile} = $opt->{op} . ".yml";
87             }
88             }
89              
90             sub execute {
91 5     5 1 47 my ( $self, $opt, $args ) = @_;
92              
93             #----------------------------#
94             # Loading
95             #----------------------------#
96 5         12 my $infile; # YAML::Syck::LoadFile handles IO::*
97 5 50       25 if ( lc $args->[0] eq 'stdin' ) {
98 0         0 $infile = *STDIN;
99             }
100             else {
101 5         16 $infile = $args->[0];
102             }
103              
104 5         14 my $s_of = {};
105 5         22 my @keys;
106 5 100       18 if ( $opt->{mk} ) {
107 3         21 my $yml = YAML::Syck::LoadFile($infile);
108 3         1009 @keys = sort keys %{$yml};
  3         28  
109              
110 3         13 for my $key (@keys) {
111             $s_of->{$key}
112 15         78 = App::RL::Common::runlist2set( $yml->{$key}, $opt->{remove} );
113             }
114             }
115             else {
116 2         7 @keys = ("__single");
117             $s_of->{__single}
118 2         15 = App::RL::Common::runlist2set( YAML::Syck::LoadFile($infile), $opt->{remove} );
119             }
120              
121             #----------------------------#
122             # Operating
123             #----------------------------#
124 5         25 my $op_result_of = { map { $_ => {} } @keys };
  17         43  
125              
126 5         18 for my $key (@keys) {
127 17         761 my $s = $s_of->{$key};
128              
129 17         34 for my $chr ( keys %{$s} ) {
  17         104  
130 17         42 my $op = $opt->{op};
131 17         70 my $op_set = $s->{$chr}->$op( $opt->{number} );
132 17         18089 $op_result_of->{$key}{$chr} = $op_set->runlist;
133             }
134             }
135              
136             #----------------------------#
137             # Output
138             #----------------------------#
139 5         289 my $out_fh;
140 5 50       28 if ( lc( $opt->{outfile} ) eq "stdout" ) {
141 5         26 $out_fh = *STDOUT;
142             }
143             else {
144 0         0 open $out_fh, ">", $opt->{outfile};
145             }
146              
147 5 100       19 if ( $opt->{mk} ) {
148 3         10 print {$out_fh} YAML::Syck::Dump($op_result_of);
  3         22  
149             }
150             else {
151 2         4 print {$out_fh} YAML::Syck::Dump( $op_result_of->{__single} );
  2         14  
152             }
153              
154 5         566 close $out_fh;
155             }
156              
157             1;