| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package App::TestOnTap::ExecMap; | 
| 2 |  |  |  |  |  |  |  | 
| 3 | 19 |  |  | 19 |  | 136 | use strict; | 
|  | 19 |  |  |  |  | 37 |  | 
|  | 19 |  |  |  |  | 573 |  | 
| 4 | 19 |  |  | 19 |  | 97 | use warnings; | 
|  | 19 |  |  |  |  | 29 |  | 
|  | 19 |  |  |  |  | 636 |  | 
| 5 |  |  |  |  |  |  |  | 
| 6 | 19 |  |  | 19 |  | 110 | use App::TestOnTap::Util qw(trim $IS_WINDOWS ensureArray); | 
|  | 19 |  |  |  |  | 37 |  | 
|  | 19 |  |  |  |  | 2039 |  | 
| 7 |  |  |  |  |  |  |  | 
| 8 | 19 |  |  | 19 |  | 9466 | use Grep::Query; | 
|  | 19 |  |  |  |  | 1016913 |  | 
|  | 19 |  |  |  |  | 12294 |  | 
| 9 |  |  |  |  |  |  |  | 
| 10 |  |  |  |  |  |  | # CTOR | 
| 11 |  |  |  |  |  |  | # | 
| 12 |  |  |  |  |  |  | sub new | 
| 13 |  |  |  |  |  |  | { | 
| 14 | 27 |  |  | 27 | 0 | 78 | my $class = shift; | 
| 15 | 27 |  |  |  |  | 70 | my $cfg = shift; | 
| 16 |  |  |  |  |  |  |  | 
| 17 | 27 |  |  |  |  | 126 | my $self = bless( {}, $class); | 
| 18 | 27 |  |  |  |  | 142 | $self->__parseExecMap($cfg); | 
| 19 |  |  |  |  |  |  |  | 
| 20 | 27 |  |  |  |  | 182 | return $self; | 
| 21 |  |  |  |  |  |  | } | 
| 22 |  |  |  |  |  |  |  | 
| 23 |  |  |  |  |  |  | sub __parseExecMap | 
| 24 |  |  |  |  |  |  | { | 
| 25 | 27 |  |  | 27 |  | 62 | my $self = shift; | 
| 26 | 27 |  |  |  |  | 60 | my $cfg = shift; | 
| 27 |  |  |  |  |  |  |  | 
| 28 | 27 |  |  |  |  | 71 | my @matcherCmdlinePairs; | 
| 29 |  |  |  |  |  |  |  | 
| 30 | 27 |  |  |  |  | 85 | my $emOrder = $cfg->{''}->{execmap}; | 
| 31 | 27 | 100 |  |  |  | 110 | if (!$emOrder) | 
| 32 |  |  |  |  |  |  | { | 
| 33 | 25 |  |  |  |  | 1034 | warn("WARNING: No execmap found, using internal default!\n"); | 
| 34 | 25 |  |  |  |  | 219 | $cfg = __defaultCfg(); | 
| 35 | 25 |  |  |  |  | 89 | $emOrder = $cfg->{''}->{execmap}; | 
| 36 |  |  |  |  |  |  | } | 
| 37 | 27 |  |  |  |  | 134 | $emOrder = ensureArray($emOrder); | 
| 38 |  |  |  |  |  |  |  | 
| 39 | 27 |  |  |  |  | 104 | foreach my $em (@$emOrder) | 
| 40 |  |  |  |  |  |  | { | 
| 41 | 202 |  |  |  |  | 714 | my $emSec = $cfg->{"EXECMAP $em"}; | 
| 42 | 202 | 50 |  |  |  | 566 | die("Missing execmap section for '$em'\n") unless $emSec; | 
| 43 |  |  |  |  |  |  |  | 
| 44 |  |  |  |  |  |  | # trip any unknown keys | 
| 45 |  |  |  |  |  |  | # | 
| 46 | 202 |  |  |  |  | 1863 | warn("WARNING: Unknown key '$_' in execmap section '$em'\n") foreach (grep(!/^(match|cmd)$/, keys(%$emSec))); | 
| 47 |  |  |  |  |  |  |  | 
| 48 |  |  |  |  |  |  | # extract the ones we want | 
| 49 |  |  |  |  |  |  | # | 
| 50 | 202 |  |  |  |  | 629 | my $match = $emSec->{match}; | 
| 51 | 202 |  | 100 |  |  | 766 | my $cmd = $emSec->{cmd} || ''; | 
| 52 | 202 | 50 |  |  |  | 452 | die("The execmap section '$em' must have at least the 'match' key\n") unless $match; | 
| 53 |  |  |  |  |  |  |  | 
| 54 |  |  |  |  |  |  | # compile the query | 
| 55 |  |  |  |  |  |  | # | 
| 56 | 202 |  |  |  |  | 820 | my $matcher = Grep::Query->new($match); | 
| 57 |  |  |  |  |  |  |  | 
| 58 |  |  |  |  |  |  | # we want to store the cmd as an array | 
| 59 |  |  |  |  |  |  | # Config::Std allows it to be in multiple forms: | 
| 60 |  |  |  |  |  |  | #   a single line (we split it on space) | 
| 61 |  |  |  |  |  |  | #   a ready-made array (take as is) | 
| 62 |  |  |  |  |  |  | #   a string with embedded \n (split on that) | 
| 63 |  |  |  |  |  |  | # | 
| 64 | 202 |  |  |  |  | 1403572 | my $cmdline = ensureArray($cmd); | 
| 65 |  |  |  |  |  |  |  | 
| 66 |  |  |  |  |  |  | # now store the matcher and cmdline in an array so we can evaluate them | 
| 67 |  |  |  |  |  |  | # in a defined order when we need to | 
| 68 |  |  |  |  |  |  | # | 
| 69 | 202 |  |  |  |  | 802 | push(@matcherCmdlinePairs, [ $matcher, $cmdline ]); | 
| 70 |  |  |  |  |  |  | } | 
| 71 |  |  |  |  |  |  |  | 
| 72 |  |  |  |  |  |  | # not much meaning in continuing if there are no mappings at all...! | 
| 73 |  |  |  |  |  |  | # | 
| 74 | 27 | 50 |  |  |  | 154 | die("No entries in the execmap\n") unless @matcherCmdlinePairs; | 
| 75 |  |  |  |  |  |  |  | 
| 76 | 27 |  |  |  |  | 513 | $self->{mcpairs} = \@matcherCmdlinePairs; | 
| 77 |  |  |  |  |  |  | } | 
| 78 |  |  |  |  |  |  |  | 
| 79 |  |  |  |  |  |  | sub __defaultCfg | 
| 80 |  |  |  |  |  |  | { | 
| 81 |  |  |  |  |  |  | # TODO: add more useful standard mappings here | 
| 82 |  |  |  |  |  |  | # | 
| 83 | 25 |  |  | 25 |  | 1033 | my %cfg = | 
| 84 |  |  |  |  |  |  | ( | 
| 85 |  |  |  |  |  |  | '' => | 
| 86 |  |  |  |  |  |  | { | 
| 87 |  |  |  |  |  |  | execmap => [qw(perl python java groovy shell autoit3 batch binary)] | 
| 88 |  |  |  |  |  |  | }, | 
| 89 |  |  |  |  |  |  | 'EXECMAP perl' => | 
| 90 |  |  |  |  |  |  | { | 
| 91 |  |  |  |  |  |  | # well, a no-brainer...:-) | 
| 92 |  |  |  |  |  |  | # | 
| 93 |  |  |  |  |  |  | 'match' => 'regexp[\.(t|pl)$]', | 
| 94 |  |  |  |  |  |  | 'cmd' => 'perl', | 
| 95 |  |  |  |  |  |  | }, | 
| 96 |  |  |  |  |  |  | 'EXECMAP python' => | 
| 97 |  |  |  |  |  |  | { | 
| 98 |  |  |  |  |  |  | # if python is preferred... | 
| 99 |  |  |  |  |  |  | # | 
| 100 |  |  |  |  |  |  | 'match' => 'regexp[\.py$]', | 
| 101 |  |  |  |  |  |  | 'cmd' => 'python', | 
| 102 |  |  |  |  |  |  | }, | 
| 103 |  |  |  |  |  |  | 'EXECMAP java' => | 
| 104 |  |  |  |  |  |  | { | 
| 105 |  |  |  |  |  |  | # quite possible and important for java shops | 
| 106 |  |  |  |  |  |  | # (couple with some nice junit and other helpers) | 
| 107 |  |  |  |  |  |  | # | 
| 108 |  |  |  |  |  |  | 'match' => 'regexp[\.jar$]', | 
| 109 |  |  |  |  |  |  | 'cmd' => [qw(java -jar)], | 
| 110 |  |  |  |  |  |  | }, | 
| 111 |  |  |  |  |  |  | 'EXECMAP groovy' => | 
| 112 |  |  |  |  |  |  | { | 
| 113 |  |  |  |  |  |  | # common variants for groovy scripts, I understand... | 
| 114 |  |  |  |  |  |  | # | 
| 115 |  |  |  |  |  |  | 'match' => 'regexp[\.(groovy|gsh|gvy|gy)$]', | 
| 116 |  |  |  |  |  |  | 'cmd' => 'groovy', | 
| 117 |  |  |  |  |  |  | }, | 
| 118 |  |  |  |  |  |  | 'EXECMAP shell' => | 
| 119 |  |  |  |  |  |  | { | 
| 120 |  |  |  |  |  |  | # shell scripting is powerful, so why not | 
| 121 |  |  |  |  |  |  | # | 
| 122 |  |  |  |  |  |  | 'match' => 'regexp[\.sh$]', | 
| 123 |  |  |  |  |  |  | 'cmd' => 'sh', | 
| 124 |  |  |  |  |  |  | }, | 
| 125 |  |  |  |  |  |  | 'EXECMAP autoit3' => | 
| 126 |  |  |  |  |  |  | { | 
| 127 |  |  |  |  |  |  | # For using AutoIt scripts (https://www.autoitscript.com/site/autoit/) | 
| 128 |  |  |  |  |  |  | # (Windows only) | 
| 129 |  |  |  |  |  |  | # | 
| 130 |  |  |  |  |  |  | 'match' => 'regexp[\.au3$]', | 
| 131 |  |  |  |  |  |  | 'cmd' => 'autoit3', | 
| 132 |  |  |  |  |  |  | }, | 
| 133 |  |  |  |  |  |  | 'EXECMAP batch' => | 
| 134 |  |  |  |  |  |  | { | 
| 135 |  |  |  |  |  |  | # possible, but perhaps not likely | 
| 136 |  |  |  |  |  |  | # (Windows only) | 
| 137 |  |  |  |  |  |  | # | 
| 138 |  |  |  |  |  |  | 'match' => 'regexp[\.(bat|cmd)$]', | 
| 139 |  |  |  |  |  |  | 'cmd' => [qw(cmd.exe /c)], | 
| 140 |  |  |  |  |  |  | }, | 
| 141 |  |  |  |  |  |  | 'EXECMAP binary' => | 
| 142 |  |  |  |  |  |  | { | 
| 143 |  |  |  |  |  |  | # for directly executable binaries, no actual 'cmd' is needed | 
| 144 |  |  |  |  |  |  | # On Windows: rename 'xyz.exe' => 'xyz.tbin' | 
| 145 |  |  |  |  |  |  | # On Unix: rename 'xyz' => 'xyz.tbin' | 
| 146 |  |  |  |  |  |  | # | 
| 147 |  |  |  |  |  |  | 'match' => 'regexp[\.tbin$]', | 
| 148 |  |  |  |  |  |  | }, | 
| 149 |  |  |  |  |  |  | ); | 
| 150 |  |  |  |  |  |  |  | 
| 151 | 25 |  |  |  |  | 130 | return \%cfg; | 
| 152 |  |  |  |  |  |  | } | 
| 153 |  |  |  |  |  |  |  | 
| 154 |  |  |  |  |  |  | # just check if the given test has a mapping | 
| 155 |  |  |  |  |  |  | # | 
| 156 |  |  |  |  |  |  | sub hasMapping | 
| 157 |  |  |  |  |  |  | { | 
| 158 | 56 |  |  | 56 | 0 | 142 | my $self = shift; | 
| 159 | 56 |  |  |  |  | 117 | my $testName = shift; | 
| 160 |  |  |  |  |  |  |  | 
| 161 | 56 |  |  |  |  | 105 | foreach my $matcherCmdlinePair (@{$self->{mcpairs}}) | 
|  | 56 |  |  |  |  | 183 |  | 
| 162 |  |  |  |  |  |  | { | 
| 163 | 70 | 100 |  |  |  | 1932 | return 1 if $matcherCmdlinePair->[0]->qgrep($testName); | 
| 164 |  |  |  |  |  |  | } | 
| 165 |  |  |  |  |  |  |  | 
| 166 | 2 | 50 |  |  |  | 267 | if (defined($self->{delegate})) | 
| 167 |  |  |  |  |  |  | { | 
| 168 | 0 | 0 |  |  |  | 0 | return 1 if $self->{delegate}->hasMapping($testName); | 
| 169 |  |  |  |  |  |  | } | 
| 170 |  |  |  |  |  |  |  | 
| 171 | 2 |  |  |  |  | 39 | return 0; | 
| 172 |  |  |  |  |  |  | } | 
| 173 |  |  |  |  |  |  |  | 
| 174 |  |  |  |  |  |  | # retrieve the cmdline map for the test | 
| 175 |  |  |  |  |  |  | # | 
| 176 |  |  |  |  |  |  | sub getMapping | 
| 177 |  |  |  |  |  |  | { | 
| 178 | 48 |  |  | 48 | 0 | 182 | my $self = shift; | 
| 179 | 48 |  |  |  |  | 145 | my $testName = shift; | 
| 180 |  |  |  |  |  |  |  | 
| 181 | 48 |  |  |  |  | 106 | foreach my $matcherCmdlinePair (@{$self->{mcpairs}}) | 
|  | 48 |  |  |  |  | 410 |  | 
| 182 |  |  |  |  |  |  | { | 
| 183 | 48 | 50 |  |  |  | 540 | return $matcherCmdlinePair->[1] if $matcherCmdlinePair->[0]->qgrep($testName); | 
| 184 |  |  |  |  |  |  | } | 
| 185 |  |  |  |  |  |  |  | 
| 186 | 0 | 0 |  |  |  |  | if (defined($self->{delegate})) | 
| 187 |  |  |  |  |  |  | { | 
| 188 | 0 |  |  |  |  |  | return $self->{delegate}->getMapping($testName); | 
| 189 |  |  |  |  |  |  | } | 
| 190 |  |  |  |  |  |  |  | 
| 191 | 0 |  |  |  |  |  | die("INTERNAL ERROR - should not reach this point!"); | 
| 192 |  |  |  |  |  |  | } | 
| 193 |  |  |  |  |  |  |  | 
| 194 |  |  |  |  |  |  | 1; |