#!/usr/bin/perl use warnings; use strict; use Data::Dumper; use Template; my (%results_by_date, %results_by_test); foreach (glob "reports/*") { my ($date) = $_ =~ m{reports/(?:[\w-])+-results-(.*)\.txt}; $results_by_date{$date} = load_report($_); } # Turn sorted-by-date structure inside out. foreach my $date (keys %results_by_date) { my $date_result = $results_by_date{$date}; foreach my $test_name (keys %$date_result) { $results_by_test{$test_name}{$date} = $date_result->{$test_name}; } } my %report_data = ( 'results' => \%results_by_test, 'test_dates' => [ sort keys %results_by_date ], ); my $tt = Template->new({ INCLUDE_PATH => 'templates', }); $tt->process('tests.tt', { 'data' => \%report_data }) or die $tt->error; # ---------------------------------------------------------------------------- sub load_report { my $file = shift; die 'No input file specified' unless $file; die "That file doesn't exist" unless -e $file; die "That isn't a plain file" unless -f _; die "That file isn't readable" unless -r _; open (my $RESULTS, '<', $file) or die "Can't open $file: $!"; my @lines = <$RESULTS>; close $RESULTS; my (%tests, $current_test); # XXX: Test files get added, removed, renamed, etc. A mechanism is necessary # here to cope with this. foreach (@lines) { chomp; if (m{^t/(.*?)\.}) { $current_test = $1; } elsif (/^ok$/) { $tests{$current_test} = 100; } elsif (/Failed .*? tests, (.*?)% okay/) { $tests{$current_test} = $1; } } \%tests; }