Files
tesla2csv/convert.pl
2020-05-20 20:37:21 +02:00

148 lines
3.8 KiB
Perl
Executable File

#!/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;
}