#!/usr/bin/env perl ############# ## imports ## ############################################################################### use strict; use warnings; ############ ## config ## ############################################################################### my $inputFilePath='./profile.log'; my $outputFilePath='./profile.csv'; my $csvSeparator='; '; ########## ## main ## ############################################################################### my %table = fileToTable($inputFilePath); my %unifiedTable = unifyTable(%table); writeCsvFile(%unifiedTable); ################# ## subroutines ## ############################################################################### # converts durations represented by strings to milliseconds # formats may look like " 2s 5ms", "5min 57s", "1min 15ms", ... sub parseDuration { my ($unparsedDuration) = @_; my @durationParts = split(/\s+/, $unparsedDuration); my $milliseconds = 0; foreach my $part(@durationParts) { my $number = $part; $number =~ s/\D//g; # remove all non number chars my $unit = $part; $unit =~ s/\d//g; # remove all number chars if ($unit eq "min") { $milliseconds += $number * 60000; } elsif ($unit eq "s") { $milliseconds += $number * 1000; } elsif ($unit eq "ms") { $milliseconds += $number; } } return $milliseconds; } ############################################################################### # read data from file and store it in hashes # $table{$module}{$mavenGoal} = $durationInMs sub fileToTable { open(my $fileHandle, '<:encoding(UTF-8)', $inputFilePath) or die "Could not open file '$inputFilePath' $!"; my %table; my $currentPackage = 'UNKNOWN'; while (my $row = <$fileHandle>) { $row =~ s/^\s+//; # trim leading&trailing whitespaces $row =~ s/\s+\z//; # remove trailing whitespace if($row eq '') { # skip empty lines next; } elsif($row =~ m/:.*:.*(\d+ms)$/) { # skip unneeded detail-lines next; } if($row =~ m/:/) { # contains colon => must be new section/package my @rowParts = split(/:/, $row); $currentPackage = $rowParts[0].':'.$rowParts[1]; } else { my ($taskName, $unparsedDuration) = split(/\s+/, $row, 2); my $durationInMs = parseDuration($unparsedDuration); $table{$currentPackage}{$taskName} = $durationInMs; } } return %table; } ############################################################################### ## ensure that all keys exist in all subtables by adding missing keys with value=0 sub unifyTable { my (%table) = @_; # create set of all keys that exist in at least one block/row/subtable my %usedKeys; foreach my $outter (keys %table) { foreach my $inner (keys %{$table{$outter}}) { if (!exists($usedKeys{$inner})) { $usedKeys{$inner} = 0; } } } # add keys if necessary foreach my $hash (keys %table) { foreach my $mustHaveKey (keys %usedKeys) { if (!exists($table{$hash}{$mustHaveKey})) { $table{$hash}{$mustHaveKey} = 0; } } } return %table; } ############################################################################### # write data to csv file (basically same format as represented by the hash) sub writeCsvFile { my (%table) = @_; open(my $out, '>:encoding(UTF-8)', $outputFilePath) or die "Could not open file '$outputFilePath' $!"; my $writeHeader = 1; foreach my $outter (keys %table) { if ($writeHeader) { print {$out} "Module${csvSeparator}"; foreach my $inner (keys %{$table{$outter}}) { print {$out} $inner."${csvSeparator}"; } print {$out} "\n"; $writeHeader = 0; } print {$out} $outter."${csvSeparator}"; foreach my $inner (keys %{$table{$outter}}) { print {$out} $table{$outter}{$inner}."${csvSeparator}"; } print {$out} "\n"; } close $out; }