File Coverage

blib/lib/RosettaCode/Task.pm
Criterion Covered Total %
statement 15 101 14.8
branch 0 30 0.0
condition 0 10 0.0
subroutine 5 9 55.5
pod 0 4 0.0
total 20 154 12.9


line stmt bran cond sub pod time code
1 1     1   7 use strict; use warnings;
  1     1   2  
  1         32  
  1         6  
  1         2  
  1         37  
2             package RosettaCode::Task;
3              
4 1     1   5 use IO::All;
  1         2  
  1         5  
5 1     1   55 use Carp 'confess';
  1         2  
  1         56  
6              
7 1     1   7 use Mo qw'build default xxx';
  1         2  
  1         5  
8              
9             extends 'RosettaCode';
10              
11             has name => '';
12             has path => '';
13             has url => '';
14             has meta => {};
15             has lang => '';
16             has prog => [];
17             has tasks => {};
18             has langs => {};
19             has bot => '';
20              
21             sub fetch_task {
22 0     0 0   my ($self) = @_;
23 0           my $file = io->file("Cache/Task/$self->{path}")->utf8;
24              
25 0 0 0       if ($file->exists and time - $file->mtime < $self->CACHE_TIME) {
26 0           $self->text($file->all);
27             }
28             else {
29 0           my $text = $self->get_text($self->name);
30 0           $file->assert->print($text);
31 0           $self->text($text);
32             }
33             }
34              
35             sub build_task {
36 0     0 0   my ($self) = @_;
37              
38 0           my $name = $self->name;
39 0           my $text = $self->text;
40 0           $text =~ s/\r//g;
41 0 0         $text =~ s/\n?\z/\n/ if length $text;
42              
43 0           $self->log("TASK $name");
44 0           my @sections = split /^==+ ?\{\{header\|(.+?)\}\}.*\n/m, $text;
45 0 0 0       if (@sections < 3 or $text !~ /<syntaxhighlight/) {
46 0           $self->log("ERROR: No implementations for '$name'");
47             }
48 0           my $head_section = shift @sections;
49 0 0         if (@sections % 2) {
50 0           $self->log("ERROR: Bad task page for '$name'");
51 0           return;
52             }
53 0           $self->parse_head_section($head_section);
54 0           my $path = $self->path;
55 0           my $file = lc($path);
56              
57 0           while (@sections) {
58 0           my ($lang, $text) = splice(@sections, 0, 2);
59 0           $lang =~ s/\|.*//;
60 0           $self->log(" $lang");
61 0           my $info = $self->langs->{lc $lang};
62 0 0         if (not defined $info) {
63 0           $self->log("ERROR: Unknown lang '$lang' ($name)");
64 0           next;
65             }
66 0           $self->parse_task_lang_section($text, $lang);
67 0           my $programs = $self->prog;
68 0 0         next unless @$programs;
69 0           my $lang_path = $info->{path};
70 0           my $ext = $info->{ext};
71 0           my $source = "Lang/$lang_path/$path";
72 0           my $target = "../../Task/$path/$lang_path";
73 0           $self->write_symlink($source, $target, 2);
74 0 0         if (@$programs == 1) {
75 0           $self->write_file(
76             "Task/$path/$lang_path/$file.$ext",
77             $programs->[0],
78             2,
79             );
80 0           next;
81             }
82 0           my $count = 1;
83 0           for (@$programs) {
84 0           $self->write_file(
85             "Task/$path/$lang_path/$file-$count.$ext",
86             $_,
87             2,
88             );
89 0           $count++;
90             }
91             }
92              
93 0           $self->meta->{from} = "http://rosettacode.org/wiki/$self->{url}";
94             $self->write_file(
95             "Task/$path/00-TASK.txt",
96             delete $self->meta->{description},
97 0           1,
98             );
99             $self->dump_file(
100             "Task/$path/00-META.yaml",
101             $self->meta,
102             1,
103 0 0         ) if %{$self->meta};
  0            
104             }
105              
106             sub parse_head_section {
107 0     0 0   my ($self, $text) = @_;
108 0           $_ = $text;
109 0           my $meta = $self->meta({});
110              
111 0           my $length = length;
112 0           while (1) {
113 0           s/\A<!--.*-->\s*//;
114 0           s/\A\[\[File:.*\s*//;
115 0           s/\A\{\{alertbox\|.*\n\s*//;
116 0           s/\A\{\{[Cc]larified-review\}\}\s*//;
117 0           s/\A\{\{[Cc]larify task\}\}\s*//;
118 0           s/\A\{\{[Oo]mit from\|.*\}\}\s*//;
119 0           s/\A\[\[[Ff]ile:.*\]\]\s*//;
120 0           s/\A\{\{[Ww]ikipedia[^\}]*\}\}\s*//;
121              
122 0 0         if (s/\A\s*\{\{requires\|(\w[\w ]*)\}\}\s*//) {
123 0   0       $meta->{requires} ||= [];
124 0           push @{$meta->{requires}}, $1;
  0            
125             }
126 0 0         if (s/\A\s*\[\[Category: *(\w[\w ]*)\]\]\s*//) {
127 0   0       $meta->{category} ||= [];
128 0           push @{$meta->{category}}, $1;
  0            
129             }
130 0 0         if (s/\A\{\{(?:[Dd]raft\s+)?[Tt]ask(?:\|([^\}]*?))?\}\}\s*//s) {
131 0 0         $meta->{note} = $1 if $1;
132             }
133              
134 0 0         last if length == $length;
135 0           $length = length;
136             }
137              
138             # Get task description text:
139 0 0         $meta->{description} = $_ if $_;
140             }
141              
142             sub parse_task_lang_section {
143 0     0 0   my ($self, $text, $lang) = @_;
144 0           local $_ = $text;
145 0           $self->lang($lang);
146 0           my $programs = $self->prog([]);
147              
148 0           while (s/<syntaxhighlight.*?>(.*?)(?:<\/syntaxhighlight>|\z)//si) {
149 0           my $program = $1;
150 0           $program =~ s/\A\s*\n//;
151 0           $program =~ s/ *$//mg;
152 0 0         $program =~ s/\n*\z/\n/ if length($program);
153 0           push @$programs, $program;
154             }
155             }
156              
157             1;