File Coverage

blib/lib/App/RL/Command/span.pm
Criterion Covered Total %
statement 82 88 93.1
branch 22 28 78.5
condition n/a
subroutine 11 11 100.0
pod 5 5 100.0
total 120 132 90.9


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