← Index
NYTProf Performance Profile   « line view »
For webmerge/scripts/webmerge.pl
  Run on Mon Oct 7 02:42:42 2013
Reported on Mon Oct 7 03:03:16 2013

Filename/home/ocbnet/domain/ocbnet.ch/vhost/webmerge/htdocs/webmerge/scripts/webmerge.pl
StatementsExecuted 353 statements in 37.8ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
11149.2ms57.5msmain::::BEGIN@144 main::BEGIN@144
11139.0ms40.4msmain::::BEGIN@235 main::BEGIN@235
11119.3ms296msmain::::BEGIN@147 main::BEGIN@147
11118.2ms34.4msmain::::BEGIN@7 main::BEGIN@7
11114.1ms109msmain::::BEGIN@31 main::BEGIN@31
11110.8ms210msmain::::BEGIN@28 main::BEGIN@28
1118.51ms28.1msmain::::BEGIN@29 main::BEGIN@29
1117.05ms8.54msmain::::BEGIN@41 main::BEGIN@41
6251046.62ms6.62msUNIVERSAL::::isaUNIVERSAL::isa (xsub)
1116.61ms81.6msmain::::BEGIN@37 main::BEGIN@37
1116.28ms8.69msmain::::BEGIN@33 main::BEGIN@33
1115.93ms142msmain::::BEGIN@34 main::BEGIN@34
1115.60ms7.98msmain::::BEGIN@35 main::BEGIN@35
1115.52ms7.67msmain::::BEGIN@36 main::BEGIN@36
1114.10ms5.83msmain::::BEGIN@46 main::BEGIN@46
1113.96ms116msmain::::BEGIN@16 main::BEGIN@16
1113.37ms4.96msmain::::BEGIN@32 main::BEGIN@32
1112.92ms4.44msmain::::BEGIN@49 main::BEGIN@49
1112.76ms142msmain::::BEGIN@40 main::BEGIN@40
1112.61ms4.05msmain::::BEGIN@47 main::BEGIN@47
1112.42ms3.93msmain::::BEGIN@50 main::BEGIN@50
1112.27ms3.72msmain::::BEGIN@48 main::BEGIN@48
1112.21ms3.67msmain::::BEGIN@51 main::BEGIN@51
1112.16ms3.68msmain::::BEGIN@52 main::BEGIN@52
1112.03ms220msmain::::BEGIN@25 main::BEGIN@25
1111.90ms3.30msmain::::BEGIN@42 main::BEGIN@42
1111.35ms167msmain::::BEGIN@43 main::BEGIN@43
92111.00ms1.00msmro::::method_changed_in mro::method_changed_in (xsub)
11211711µs711µsInternals::::SvREADONLYInternals::SvREADONLY (xsub)
8741661µs661µsmain::::CORE:subst main::CORE:subst (opcode)
40114534µs534µsUNIVERSAL::::canUNIVERSAL::can (xsub)
554385µs385µsUNIVERSAL::::VERSIONUNIVERSAL::VERSION (xsub)
111211µs410msmain::::get_xml main::get_xml
111208µs506msmain::::read_xml main::read_xml
11195µs102µsFcntl::::O_NOINHERIT Fcntl::O_NOINHERIT
21180µs80µsmain::::CORE:substcont main::CORE:substcont (opcode)
11172µs80µsFcntl::::O_TEMPORARY Fcntl::O_TEMPORARY
11169µs76µsFcntl::::O_EXLOCK Fcntl::O_EXLOCK
11159µs317µsmain::::BEGIN@30 main::BEGIN@30
11154µs145µsmain::::BEGIN@8 main::BEGIN@8
11152µs84µsmain::::BEGIN@9 main::BEGIN@9
11150µs50µsmain::::END main::END
11145µs63µsmain::::checkFile main::checkFile
11140µs40µsversion::::(bool version::(bool (xsub)
11140µs40µsmain::::BEGIN@20 main::BEGIN@20
11127µs27µsversion::::(cmp version::(cmp (xsub)
33124µs24µsmain::::CORE:match main::CORE:match (opcode)
11118µs18µsmain::::CORE:ftis main::CORE:ftis (opcode)
0000s0smain::::RUNTIME main::RUNTIME
0000s0smain::::__ANON__[webmerge/scripts/webmerge.pl:470] main::__ANON__[webmerge/scripts/webmerge.pl:470]
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
06282µsProfile data that couldn't be associated with a specific line:
# spent 146µs making 1 call to File::Temp::END # spent 51µs making 1 call to XML::LibXML::END # spent 50µs making 1 call to main::END # spent 14µs making 1 call to RTP::Webmerge::END # spent 12µs making 1 call to RTP::Webmerge::Watchdog::END # spent 10µs making 1 call to IPC::Run3::END
11316µs#!/usr/bin/perl
2################################################################################
3# Copyright 2013 by Marcel Greter
4# This file is part of Webmerge (GPL3)
5################################################################################
6
72783µs234.8ms
# spent 34.4ms (18.2+16.2) within main::BEGIN@7 which was called: # once (18.2ms+16.2ms) by main::RUNTIME at line 7
use Carp;
# spent 34.4ms making 1 call to main::BEGIN@7 # spent 355µs making 1 call to Exporter::import
82140µs2237µs
# spent 145µs (54+92) within main::BEGIN@8 which was called: # once (54µs+92µs) by main::RUNTIME at line 8
use strict;
# spent 145µs making 1 call to main::BEGIN@8 # spent 92µs making 1 call to strict::import
92170µs2115µs
# spent 84µs (52+32) within main::BEGIN@9 which was called: # once (52µs+32µs) by main::RUNTIME at line 9
use warnings;
# spent 84µs making 1 call to main::BEGIN@9 # spent 32µs making 1 call to warnings::import
10
11################################################################################
12
13# use FindBin to find the path to the script
14# from here the config file for be relative
15# this is not true if config path is absolute
162962µs2126ms
# spent 116ms (3.96+112) within main::BEGIN@16 which was called: # once (3.96ms+112ms) by main::RUNTIME at line 16
use FindBin qw($Bin);
# spent 116ms making 1 call to main::BEGIN@16 # spent 9.98ms making 1 call to Exporter::import
17
18# insert our module directory to lib search directory
19# we want to keep our modules local and not install global
201152µs140µs
# spent 40µs within main::BEGIN@20 which was called: # once (40µs+0s) by main::RUNTIME at line 20
BEGIN { unshift @INC, "$Bin/modules"; }
# spent 40µs making 1 call to main::BEGIN@20
21
22################################################################################
23
24# load spriteset library
252735µs1220ms
# spent 220ms (2.03+218) within main::BEGIN@25 which was called: # once (2.03ms+218ms) by main::RUNTIME at line 25
use OCBNET::Spritesets;
# spent 220ms making 1 call to main::BEGIN@25
26
27# load local modules
282607µs2211ms
# spent 210ms (10.8+200) within main::BEGIN@28 which was called: # once (10.8ms+200ms) by main::RUNTIME at line 28
use RTP::Webmerge;
# spent 210ms making 1 call to main::BEGIN@28 # spent 313µs making 1 call to Exporter::import
292604µs228.4ms
# spent 28.1ms (8.51+19.6) within main::BEGIN@29 which was called: # once (8.51ms+19.6ms) by main::RUNTIME at line 29
use RTP::Webmerge::IO;
# spent 28.1ms making 1 call to main::BEGIN@29 # spent 232µs making 1 call to Exporter::import
302155µs2575µs
# spent 317µs (59+258) within main::BEGIN@30 which was called: # once (59µs+258µs) by main::RUNTIME at line 30
use RTP::Webmerge::Path;
# spent 317µs making 1 call to main::BEGIN@30 # spent 258µs making 1 call to Exporter::import
312605µs2109ms
# spent 109ms (14.1+94.5) within main::BEGIN@31 which was called: # once (14.1ms+94.5ms) by main::RUNTIME at line 31
use RTP::Webmerge::Merge;
# spent 109ms making 1 call to main::BEGIN@31 # spent 226µs making 1 call to Exporter::import
322614µs25.14ms
# spent 4.96ms (3.37+1.59) within main::BEGIN@32 which was called: # once (3.37ms+1.59ms) by main::RUNTIME at line 32
use RTP::Webmerge::Prepare;
# spent 4.96ms making 1 call to main::BEGIN@32 # spent 184µs making 1 call to Exporter::import
332744µs28.98ms
# spent 8.69ms (6.28+2.41) within main::BEGIN@33 which was called: # once (6.28ms+2.41ms) by main::RUNTIME at line 33
use RTP::Webmerge::HeadInc;
# spent 8.69ms making 1 call to main::BEGIN@33 # spent 294µs making 1 call to Exporter::import
342629µs2142ms
# spent 142ms (5.93+136) within main::BEGIN@34 which was called: # once (5.93ms+136ms) by main::RUNTIME at line 34
use RTP::Webmerge::Embedder;
# spent 142ms making 1 call to main::BEGIN@34 # spent 220µs making 1 call to Exporter::import
352726µs28.59ms
# spent 7.98ms (5.60+2.39) within main::BEGIN@35 which was called: # once (5.60ms+2.39ms) by main::RUNTIME at line 35
use RTP::Webmerge::Optimize;
# spent 7.98ms making 1 call to main::BEGIN@35 # spent 604µs making 1 call to Exporter::import
362796µs27.87ms
# spent 7.67ms (5.52+2.15) within main::BEGIN@36 which was called: # once (5.52ms+2.15ms) by main::RUNTIME at line 36
use RTP::Webmerge::Checksum;
# spent 7.67ms making 1 call to main::BEGIN@36 # spent 198µs making 1 call to Exporter::import
372621µs281.8ms
# spent 81.6ms (6.61+75.0) within main::BEGIN@37 which was called: # once (6.61ms+75.0ms) by main::RUNTIME at line 37
use RTP::Webmerge::Watchdog;
# spent 81.6ms making 1 call to main::BEGIN@37 # spent 202µs making 1 call to Exporter::import
38
39# load additional modules (no import)
402565µs1142ms
# spent 142ms (2.76+139) within main::BEGIN@40 which was called: # once (2.76ms+139ms) by main::RUNTIME at line 40
use RTP::Webmerge::Compile::JS qw();
# spent 142ms making 1 call to main::BEGIN@40
412567µs18.54ms
# spent 8.54ms (7.05+1.48) within main::BEGIN@41 which was called: # once (7.05ms+1.48ms) by main::RUNTIME at line 41
use RTP::Webmerge::Compile::CSS qw();
# spent 8.54ms making 1 call to main::BEGIN@41
422536µs13.30ms
# spent 3.30ms (1.90+1.40) within main::BEGIN@42 which was called: # once (1.90ms+1.40ms) by main::RUNTIME at line 42
use RTP::Webmerge::Process::JS qw();
# spent 3.30ms making 1 call to main::BEGIN@42
432581µs1167ms
# spent 167ms (1.35+166) within main::BEGIN@43 which was called: # once (1.35ms+166ms) by main::RUNTIME at line 43
use RTP::Webmerge::Process::CSS qw();
# spent 167ms making 1 call to main::BEGIN@43
44
45# load optimizer modules (no import)
462596µs15.83ms
# spent 5.83ms (4.10+1.73) within main::BEGIN@46 which was called: # once (4.10ms+1.73ms) by main::RUNTIME at line 46
use RTP::Webmerge::Optimize::TXT qw();
# spent 5.83ms making 1 call to main::BEGIN@46
472569µs14.05ms
# spent 4.05ms (2.61+1.44) within main::BEGIN@47 which was called: # once (2.61ms+1.44ms) by main::RUNTIME at line 47
use RTP::Webmerge::Optimize::GIF qw();
# spent 4.05ms making 1 call to main::BEGIN@47
482559µs13.72ms
# spent 3.72ms (2.27+1.45) within main::BEGIN@48 which was called: # once (2.27ms+1.45ms) by main::RUNTIME at line 48
use RTP::Webmerge::Optimize::JPG qw();
# spent 3.72ms making 1 call to main::BEGIN@48
492602µs14.44ms
# spent 4.44ms (2.92+1.52) within main::BEGIN@49 which was called: # once (2.92ms+1.52ms) by main::RUNTIME at line 49
use RTP::Webmerge::Optimize::PNG qw();
# spent 4.44ms making 1 call to main::BEGIN@49
502602µs13.93ms
# spent 3.93ms (2.42+1.51) within main::BEGIN@50 which was called: # once (2.42ms+1.51ms) by main::RUNTIME at line 50
use RTP::Webmerge::Optimize::MNG qw();
# spent 3.93ms making 1 call to main::BEGIN@50
512534µs13.67ms
# spent 3.67ms (2.21+1.46) within main::BEGIN@51 which was called: # once (2.21ms+1.46ms) by main::RUNTIME at line 51
use RTP::Webmerge::Optimize::ZIP qw();
# spent 3.67ms making 1 call to main::BEGIN@51
5221.06ms13.68ms
# spent 3.68ms (2.16+1.51) within main::BEGIN@52 which was called: # once (2.16ms+1.51ms) by main::RUNTIME at line 52
use RTP::Webmerge::Optimize::GZ qw();
# spent 3.68ms making 1 call to main::BEGIN@52
53
54################################################################################
55# get the mother pid
56################################################################################
57
58114µsmy $pid = $$;
59
60################################################################################
61# declare and init configuration options
62################################################################################
63
64173µsmy $config =
65{
66
67 # where is you htdocs root directory
68 # this is needed to create absolute urls
69 # default is relative to the config file
70 'webroot' => '{CONF}/..',
71
72 # define a current working directory
73 # you can adjust this also in the xml config
74 # it's also possible to change it only for a block
75 'directory' => '{WWW}',
76
77 # default configuration file relative from our webroot
78 # this is the main source for all other configuration options
79 'configfile' => '{EXT}/conf/webmerge.conf.xml',
80
81 # header to prepend to all generated merge output files
82 'headtmpl' => "/* autogenerated by webmerge (%s context) */\n",
83
84 # doctype to render includes
85 'doctype' => 'html5',
86
87 # debug mode
88 'debug' => 0,
89
90 # preapre stuff
91 'prepare' => 1,
92 # optimize stuff
93 'optimize' => 0,
94 # optimize level
95 'level' => 2,
96 # merge configured stuff
97 'merge' => 1,
98 # create head includes
99 'headinc' => 0,
100 # create embedder
101 'embedder' => 0,
102 # start watchdog
103 'watchdog' => 0,
104
105 # license stuff
106 'license' => 1,
107 # compile stuff
108 'compile' => 1,
109 # minify stuff
110 'minify' => 1,
111 # join stuff
112 'join' => 1,
113 # dev stuff
114 'dev' => 1,
115
116 # do end crc-check
117 'crc-check' => 0,
118
119 # various crc features
120 'crc-file' => 1,
121 'crc-comment' => 1,
122
123 # referer for downloads
124 'referer' => undef,
125
126 # parallel jobs
127 'jobs' => 2,
128
129 # the order in which to prefer to include stuff
130 'incorder' =>
131 {
132 'dev' => ['dev', 'join', 'minify', 'compile'],
133 'live' => ['compile', 'minify', 'join', 'dev']
134 }
135
136};
137# EO config
138
139################################################################################
140# get config options from the command line
141################################################################################
142
143# load commandline option fetcher
1442812µs258.5ms
# spent 57.5ms (49.2+8.21) within main::BEGIN@144 which was called: # once (49.2ms+8.21ms) by main::RUNTIME at line 144
use Getopt::Long qw(GetOptions);
# spent 57.5ms making 1 call to main::BEGIN@144 # spent 1.04ms making 1 call to Getopt::Long::import
145
146# load help message generator
14722.32ms2296ms
# spent 296ms (19.3+276) within main::BEGIN@147 which was called: # once (19.3ms+276ms) by main::RUNTIME at line 147
use Pod::Usage qw(pod2usage);
# spent 296ms making 1 call to main::BEGIN@147 # spent 247µs making 1 call to Exporter::import
148
149# command line only options
150# cannot be overriden by config
15116µsmy ($man, $help, $opts) = (0, 0, 0);
152
153# create the options array
1541166µs11.44msmy @opts = (
# spent 1.44ms making 1 call to RTP::Webmerge::initConfig
155
156 # the main config file (only from cmd line)
157 'configfile|f=s' => \$config->{'configfile'},
158
159 # enable/disable debug mode
160 'debug|dbg!' => \$config->{'cmd_debug'},
161
162 # maybe change these in the config file
163 'webroot=s' => \$config->{'cmd_webroot'},
164 'doctype|d=s' => \$config->{'cmd_doctype'},
165
166 # enable/disable base operations
167 'prepare|p!' => \$config->{'cmd_prepare'},
168 'optimize|o!' => \$config->{'cmd_optimize'},
169 'level|l=o' => \$config->{'cmd_level'},
170 'merge|m!' => \$config->{'cmd_merge'},
171 'headinc|i!' => \$config->{'cmd_headinc'},
172 'embedder|e!' => \$config->{'cmd_embedder'},
173 'watchdog|w!' => \$config->{'cmd_watchdog'},
174 'crc-check|c!' => \$config->{'cmd_crc-check'},
175
176 # various crc features
177 'crc-file!' => \$config->{'cmd_crc-file'},
178 'crc-comment!' => \$config->{'cmd_crc-comment'},
179
180 # enable/disable stage operations
181 'license!' => \$config->{'cmd_license'},
182 'compile!' => \$config->{'cmd_compile'},
183 'minify!' => \$config->{'cmd_minify'},
184 'join!' => \$config->{'cmd_join'},
185 'dev!' => \$config->{'cmd_dev'},
186
187 # referer http header for downloads
188 'referer|r=s' => \$config->{'cmd_referer'},
189
190 # header tempalte to prepend to files
191 'headtmpl|h=s' => \$config->{'cmd_headtmpl'},
192
193 # number of commands to run simultaneously
194 'jobs|j=i' => \$config->{'cmd_jobs'},
195
196 # usage/help options
197 'help|?' => \$help,
198 'opts' => \$opts,
199 'man' => \$man,
200
201 # init config will prepare additional configuration
202 # returns additional options to be fetched from cmd
203 initConfig($config)
204
205);
206# EO @options
207
208# get options from commandline
209130µs1245µsGetOptions(@opts) or pod2usage(2);
# spent 245µs making 1 call to Getopt::Long::GetOptions
210
211################################################################################
212
213# uncomment if you want to see all options
21412µsif ($opts)
215{
216 print join("\n", map {
217 s/(?:\!|\=.*?)$//;
218 join(', ', map { '-' . $_ } split /\|/);
219 } sort keys %{ { @opts } });
220}
221
222################################################################################
223
224# show help page
2251500nspod2usage(1) if $help;
226
227# show man page if requested by command line
22811µspod2usage(-exitval => 0, -verbose => 2) if $man;
229
230################################################################################
231# read the configuration file
232################################################################################
233
234# load xml module
235211.8ms240.5ms
# spent 40.4ms (39.0+1.43) within main::BEGIN@235 which was called: # once (39.0ms+1.43ms) by main::RUNTIME at line 235
use XML::Simple;
# spent 40.4ms making 1 call to main::BEGIN@235 # spent 117µs making 1 call to XML::Simple::import
236
237# search for the config file
23814µsmy $configfile = 'webmerge.conf.xml';
239
240# register extension path within our path modules for later use
241125µs1881µs$RTP::Webmerge::Path::extroot = check_path(join('/', $Bin, '..'));
# spent 881µs making 1 call to RTP::Webmerge::Path::check_path
242
243# helper sub to check file for existence
244172µs118µs
# spent 63µs (45+18) within main::checkFile which was called: # once (45µs+18µs) by main::RUNTIME at line 247
sub checkFile { defined $_[0] && -e $_[0] ? $_[0] : undef; }
# spent 18µs making 1 call to main::CORE:ftis
245
246# check if configfile is given as relative path
247167µs3696µsunless ( $config->{'configfile'} =~ m/^\// )
# spent 626µs making 1 call to RTP::Webmerge::Path::check_path # spent 63µs making 1 call to main::checkFile # spent 6µs making 1 call to main::CORE:match
248{
249 # search for the config file
250 $config->{'configfile'} =
251 # first try from current directory
252 checkFile(check_path($config->{'configfile'}));
253}
254
255# abort if the configuration file was not found
25613µsdie "configfile not found" unless $config->{'configfile'};
257
258# create the config path from config file ...
25917µs$config->{'configpath'} = $config->{'configfile'};
260# ... and remove the trailing filename
261155µs126µs$config->{'configpath'} =~ s/\/[^\/]+$//;
# spent 26µs making 1 call to main::CORE:subst
262
263# register path within our path modules for later use
26414µs$RTP::Webmerge::Path::confroot = $config->{'configpath'};
265
266
267################################################################################
268# xml helper function for the include directive
269################################################################################
270
271# returns xml fragment as string
272# read the given file and do includes
273sub get_xml
274
# spent 410ms (211µs+410) within main::get_xml which was called: # once (211µs+410ms) by main::read_xml at line 316
{
275
276 # get the filenname
277112µs my ($file, @config) = @_;
278
279 # resolve the file path
280113µs1784µs $file = check_path($file);
# spent 784µs making 1 call to RTP::Webmerge::Path::check_path
281
282 # read the complete xml file
283115µs11.15ms my $data = readfile($file) || return;
# spent 1.15ms making 1 call to RTP::Webmerge::IO::readfile
284
285 # replace include tags with the real content of the file to be included
286128µs110µs ${$data} =~ s/<include\s+src=(?:\'([^\']+)\'|\"([^\"]+)\"|(\w+))\s*\/?>/get_xml($1||$2||$3)/egm;
# spent 10µs making 1 call to main::CORE:subst
287
288 # parse and create the xml document
289121µs1395ms my $xml = XMLin(${$data}, 'ForceArray' => 1, 'KeyAttr' => []);
# spent 395ms making 1 call to XML::Simple::XMLin
290
291 # return the xml fragment
292196µs113.0ms return XMLout($xml, 'KeyAttr' => [], 'RootName' => undef);
# spent 13.0ms making 1 call to XML::Simple::XMLout
293
294}
295# EO get_xml
296
297
298# returns xml document as object
299# read the given file and do includes
300sub read_xml
301
# spent 506ms (208µs+506) within main::read_xml which was called: # once (208µs+506ms) by main::RUNTIME at line 333
{
302
303 # get the filenname
30417µs my ($file, @config) = @_;
305
306 # resolve the file path
307111µs1732µs $file = check_path($file);
# spent 732µs making 1 call to RTP::Webmerge::Path::check_path
308
309 # read the complete xml file
310115µs11.62ms my $data = readfile($file) || return;
# spent 1.62ms making 1 call to RTP::Webmerge::IO::readfile
311
312 # die if config file is empty
31312µs die "empty config file <$file>" if ${$data} eq "";
314
315 # replace include tags with the real content of the file to be included
3161208µs4411ms ${$data} =~ s/<include\s+src=(?:\'([^\']+)\'|\"([^\"]+)\"|(\w+))\s*\/?>/get_xml($1||$2||$3)/egm;
# spent 410ms making 1 call to main::get_xml # spent 80µs making 2 calls to main::CORE:substcont, avg 40µs/call # spent 45µs making 1 call to main::CORE:subst
317
318 # parse and create the xml document
319120µs193.0ms my $xml = XMLin(${$data}, 'ForceArray' => 1, 'KeyAttr' => []);
# spent 93.0ms making 1 call to XML::Simple::XMLin
320
321 # return XML doc
322130µs return $xml;
323
324}
325# EO read_xml
326
327
328################################################################################
329# read and parse the xml configuration
330################################################################################
331
332# parse the xml configuration file
333115µs1506msmy $xml = read_xml($config->{'configfile'})
# spent 506ms making 1 call to main::read_xml
334 or die 'error while reading config file, aborting';
335
336
337################################################################################
338# apply the configuration from the xml to the config hash
339################################################################################
340
341# process all config nodes in config file
342112µsforeach my $cfg (@{$xml->{'config'} || []})
343{
344
345 # process all given configuration keys
346240µs foreach my $key (keys %{$cfg || {}})
347 {
348
349 # do not create unknown config keys
3501854µs next unless exists $config->{$key};
351
352 # assign the value from the first item
35318103µs $config->{$key} = $cfg->{$key}->[0];
354
355 # if we got a hash we had an empty tag
3561869µs if (ref($config->{$key}) eq 'HASH')
357 { $config->{$key} = ''; }
358
359 }
360 # EO each xml config key
361
362}
363# EO each xml config
364
365# store xml reference
36614µs$config->{'xml'} = $xml;
367
368
369################################################################################
370# apply overruling command line options after xml has been applied
371################################################################################
372
373# search all config keys for /^cmd_/
374# options from command line overrule
375# all other configuration options
3761205µsforeach my $key (keys %{$config})
377{
378
379 # only process cmd keys
380841.52ms84580µs next unless $key =~ s/^cmd_//;
# spent 580µs making 84 calls to main::CORE:subst, avg 7µs/call
381
382 # only process valid cmd keys
38342206µs next unless defined $config->{'cmd_'.$key};
384
385 # overrule the option from cmd line
386525µs $config->{$key} = $config->{'cmd_'.$key};
387
388 # remove cmd option from config
389534µs delete $config->{'cmd_'.$key};
390
391}
392# EO each config key
393
394################################################################################
395# setup some paths to be used by all other functions
396################################################################################
397
398# set htdocs root directory and current working directory
399120µs1886µs$RTP::Webmerge::Path::webroot = check_path($config->{'webroot'} || '.');
# spent 886µs making 1 call to RTP::Webmerge::Path::check_path
400117µs1770µs$RTP::Webmerge::Path::directory = check_path($config->{'directory'} || '.');
# spent 770µs making 1 call to RTP::Webmerge::Path::check_path
401
402################################################################################
403
404# only allow directory or query option to be given for fingerprinting
405134µs111µsif ($config->{'fingerprint-dev'} && !($config->{'fingerprint-dev'} =~ m/^[qfn]/i))
# spent 11µs making 1 call to main::CORE:match
406{ die "invalid fingerprinting set for dev: <" . $config->{'fingerprint-dev'} . ">"; }
407128µs17µsif ($config->{'fingerprint-live'} && !($config->{'fingerprint-live'} =~ m/^[qfn]/i))
# spent 7µs making 1 call to main::CORE:match
408{ die "invalid fingerprinting set for live: <" . $config->{'fingerprint-live'} . ">"; }
409
410# normalize fingerprint configuration to the first letter (lowercase)
411117µs$config->{'fingerprint-dev'} = lc substr($config->{'fingerprint-dev'}, 0, 1);
412110µs$config->{'fingerprint-live'} = lc substr($config->{'fingerprint-live'}, 0, 1);
413# disable the fingerprint option if the given value is no or none
41413µs$config->{'fingerprint-dev'} = undef if $config->{'fingerprint-dev'} eq 'n';
41512µs$config->{'fingerprint-live'} = undef if $config->{'fingerprint-live'} eq 'n';
416
417
418################################################################################
419# setup configuration for external downloads
420# so far this can only be set by the config file
421################################################################################
422
423# init the config array
42417µs$config->{'external'} = [];
425
426# process all config nodes in config file
427110µsforeach my $cfg (@{$xml->{'config'} || []})
428{
429
430 # process all given external options
431220µs foreach my $ext (@{$cfg->{'external'} || []})
432 {
433
434 # get content from xml node
435 my $enabled = $ext->{'content'};
436 # enable when tag was self closing
437 $enabled = 1 unless defined $enabled;
438 # push hash object to config array
439 unshift @{$config->{'external'}},
440 {
441 'enabled' => $enabled,
442 'href' => $ext->{'href'},
443 'referer' => $ext->{'referer'},
444 };
445
446 }
447 # EO each external
448
449}
450# EO each xml config
451
452
453################################################################################
454# declare status variables and attach to config hash
455################################################################################
456
457# store atomic operations
45815µs$config->{'atomic'} = {};
459
460# store temporarily files
46114µs$config->{'temps'} = [];
462
463
464################################################################################
465# setup teardown handlers before main program
466################################################################################
467
468# exit on ctrl+c, this make sure
469# that the end handler is called
470146µslocal $SIG{'INT'} = sub { exit; };
471
472# this will always be called
473# when the main script exists
474END
475
# spent 50µs within main::END which was called: # once (50µs+0s) by main::RUNTIME at line 0
{
476 # only mother takes care of this
477135µs if ($pid == $$)
478 {
479 # delete all temporarily created files
480112µs foreach (@{$config->{'temps'} || []}) { unlink $_ if -e $_; }
481 # delete all atomic temporarily files (struct: [data, blessed])
482115µs foreach (values %{$config->{'atomic'} || {}}) { $_->[1]->delete; }
483 }
484 # EO if mother
485}
486
487
488################################################################################
489# check the configuration before goind to execute main program
490################################################################################
491
492# check config will assert the configuration
493# call after you have read command line options
494115µs13.40mscheckConfig($config) or die "config check failed";
# spent 3.40ms making 1 call to RTP::Webmerge::checkConfig
495
496
497################################################################################
498# remove xml for not mentioned steps
499################################################################################
500
501# if some arguments are given we only want to merge given steps
502# therefore remove all other steps from the configuration file
50313µsif (scalar(@ARGV))
504{
505
506 # create regular expression to match steps
507 my $re_argv = join('|', @ARGV);
508
509 # loop all operation nodes (which could have an step)
510 foreach my $node
511 (
512 @{$xml->{'merge'} || []},
513 @{$xml->{'prepare'} || []},
514 @{$xml->{'headinc'} || []},
515 @{$xml->{'embedder'} || []},
516 @{$xml->{'optimize'} || []},
517 )
518 {
519
520 # get all subnodes from the main operation nodes
521 my @subnodes = grep { ref($_) eq 'ARRAY' } values %{$node};
522
523 # should we keep the root node
524 # otheriwse it may be disabled
525 my $keep_root = 0;
526
527 # keep all subnodes if the root node should be generated
528 my $keep_sub = $node->{'step'} && $node->{'step'} =~ m/^(?:$re_argv)$/;
529
530 # process each subnode
531 foreach my $subnode (map { @{$_} } @subnodes)
532 {
533
534 # abort loop if we want to keep all subnodes
535 # othwerwise it may be disabled if step doesn't match
536 next if $keep_sub || ref($subnode) ne 'HASH';
537
538 # only can remove items with step
539 next unless $subnode->{'step'};
540
541 # test if we should disable this node from the xml
542 unless ($subnode->{'step'} =~ m/^(?:$re_argv)$/)
543 {
544
545 # simply disable this subnode
546 $subnode->{'disabled'} = 'true';
547
548 }
549 else
550 {
551
552 # keep this root node
553 $keep_root = 1;
554
555 }
556 # EO if step matches argv
557
558 }
559 # EO each subnode
560
561 # abort loop if we want to keep the root node
562 # othwerwise it may be disabled if step doesn't match
563 next if $keep_root;
564
565 # only can remove items with step
566 next unless $node->{'step'};
567
568 # test if we should disable this node from the xml
569 unless ($node->{'step'} =~ m/^(?:$re_argv)$/)
570 {
571
572 # simply disable this node
573 $node->{'disabled'} = 'true';
574
575 }
576 # EO if disable node
577
578 }
579 # EO foreach nodes
580
581}
582# EO input arguments
583
584
585################################################################################
586# remove xml for dublicate ids (only use last)
587################################################################################
588
589# get nodes arrays to clean
590129µsforeach my $nodes
591(
592 ($xml->{'prepare'} || []),
593 ($xml->{'headinc'} || []),
594 ($xml->{'feature'} || []),
595 ($xml->{'embedder'} || []),
596 ($xml->{'optimize'} || []),
597 (map { $_->{'js'} || [] } @{$xml->{'merge'} || []}),
598 (map { $_->{'css'} || [] } @{$xml->{'merge'} || []})
599)
600{
601
602 # count block occurences
603 # blocks identified by id
60475µs my %known_id;
605
606 # loop from behind so we can splice items out
607771µs for (my $i = $#{$nodes}; $i != -1; -- $i)
608 {
609
610 # the the id of this block (skip if undefined)
611836µs my $id = $nodes->[$i]->{'id'} || next;
612
613 # increment id counter
614 # will init automatically
615626µs $known_id{$id} += 1;
616
617 # always keep the first node
618 # the loop is going from behind
619 # so this is actually the last node
620620µs next if ($known_id{$id} == 1);
621
622 # splice out all other nodes with
623 # the same type and identifier
624 splice(@{$nodes}, $i, 1);
625
626 }
627
628}
629# EO loop arrays to clean
630
631
632################################################################################
633# main execution of the operations
634################################################################################
635
63614µsunless ($config->{'watchdog'})
637{
638
639 # call the action step first
640 # this will create directories
64116µs if ($config->{'prepare'} && $xml->{'prepare'})
642138µs23.76ms { prepare($config, $_) foreach @{$xml->{'prepare'}}; }
# spent 3.76ms making 2 calls to RTP::Webmerge::Prepare::prepare, avg 1.88ms/call
643
644 # call the optimization step next
645 # this will change some source files
64614µs if ($config->{'optimize'} && $xml->{'optimize'})
647 { optimizer($config, $_) foreach @{$xml->{'optimize'}}; }
648
649 # next we will continue with the merge step
650 # this will write generated and processed files
65117µs if ($config->{'merge'} && $xml->{'merge'})
652127µs1419s { merger($config, $_) foreach @{$xml->{'merge'}}; }
# spent 419s making 1 call to RTP::Webmerge::Merge::merger
653
654 # call headinc function to generate headers
655 # these can be included as standalone files
656 # they have includes for all the css and js files
65719µs if ($config->{'headinc'} && $xml->{'headinc'})
658 { headinc($config, $_) foreach @{$xml->{'headinc'}}; }
659
660 # call embedder to create standalone embedder code
661 # this code will sniff the environment to choose
662 # the correct headinc to be included in the html
66314µs if ($config->{'embedder'} && $xml->{'embedder'})
664 { embedder($config, $_) foreach @{$xml->{'embedder'}}; }
665
666}
667
668################################################################################
669# now commit all changes
670################################################################################
671
672# reset atomic operations
673# this will commit all changes
674150µs$config->{'atomic'} = {};
675
676# delete all temporarily created files
67712.59ms3929.2msforeach (@{$config->{'temps'} || []})
# spent 29.2ms making 39 calls to RTP::IO::AtomicFile::DESTROY, avg 748µs/call
678{ unlink $_ if -e $_; }
679
680# reset temporarily files
68118µs$config->{'temps'} = [];
682
683################################################################################
684# start the watchdog at the end to monitor changes
685################################################################################
686
687# call watchdog to watch for file changes
688# will call merge directly if something changes
689# also takes care of atomic and temps operations
690# attention: watchdog will never return control
69112µswatchdog($config) if ($config->{'watchdog'});
692
693################################################################################
694# check for data integrity after commiting changes
695################################################################################
696
697# call crc check function to ensure integrity
698126µs154.1scrcCheck($config) if ($config->{'crc-check'});
# spent 54.1s making 1 call to RTP::Webmerge::Checksum::crcCheck
699
700################################################################################
701################################################################################
7021118µs1;
703
704__DATA__
 
# spent 711µs within Internals::SvREADONLY which was called 112 times, avg 6µs/call: # 112 times (711µs+0s) by constant::import at line 147 of constant.pm, avg 6µs/call
sub Internals::SvREADONLY; # xsub
# spent 385µs within UNIVERSAL::VERSION which was called 5 times, avg 77µs/call: # once (104µs+0s) by Pod::Select::BEGIN@242 at line 242 of Pod/Select.pm # once (85µs+0s) by Pod::Simple::BEGIN@8 at line 8 of Pod/Simple.pm # once (68µs+0s) by File::Temp::BEGIN@144 at line 144 of File/Temp.pm # once (64µs+0s) by JSON::BEGIN@2 at line 2 of (eval 17)[JSON.pm:252] # once (63µs+0s) by File::Temp::BEGIN@146 at line 146 of File/Temp.pm
sub UNIVERSAL::VERSION; # xsub
# spent 534µs within UNIVERSAL::can which was called 40 times, avg 13µs/call: # 17 times (284µs+0s) by RTP::Webmerge::Path::BEGIN@43 at line 41 of File/Spec/Functions.pm, avg 17µs/call # 4 times (42µs+0s) by XML::SAX::Base::xml_decl at line 446 of XML/SAX/Base.pm, avg 11µs/call # 4 times (42µs+0s) by XML::SAX::Base::comment at line 2355 of XML/SAX/Base.pm, avg 10µs/call # 2 times (22µs+0s) by XML::SAX::Base::parse at line 2609 of XML/SAX/Base.pm, avg 11µs/call # 2 times (22µs+0s) by XML::SAX::ParserFactory::parser at line 36 of XML/SAX/ParserFactory.pm, avg 11µs/call # 2 times (21µs+0s) by XML::SAX::Base::start_document at line 1251 of XML/SAX/Base.pm, avg 10µs/call # 2 times (20µs+0s) by XML::SAX::Base::end_document at line 1435 of XML/SAX/Base.pm, avg 10µs/call # 2 times (17µs+0s) by XML::SAX::Base::end_element at line 2194 of XML/SAX/Base.pm, avg 9µs/call # 2 times (17µs+0s) by XML::SAX::Base::start_element at line 285 of XML/SAX/Base.pm, avg 9µs/call # 2 times (16µs+0s) by XML::SAX::Base::characters at line 193 of XML/SAX/Base.pm, avg 8µs/call # once (30µs+0s) by attributes::import at line 59 of attributes.pm
sub UNIVERSAL::can; # xsub
# spent 6.62ms within UNIVERSAL::isa which was called 625 times, avg 11µs/call: # 268 times (3.47ms+0s) by OCBNET::Spritesets::Canvas::Repeater::repeater at line 49 of webmerge/scripts/modules/OCBNET/Spritesets/Canvas/Repeater.pm, avg 13µs/call # 130 times (1000µs+0s) by XML::Simple::collapse at line 1076 of XML/Simple.pm, avg 8µs/call # 108 times (1.10ms+0s) by OCBNET::Spritesets::Canvas::Layout::layout at line 386 of webmerge/scripts/modules/OCBNET/Spritesets/Canvas/Layout.pm, avg 10µs/call # 56 times (328µs+0s) by XML::Simple::value_to_xml at line 1461 of XML/Simple.pm, avg 6µs/call # 32 times (220µs+0s) by XML::Simple::value_to_xml at line 1446 of XML/Simple.pm, avg 7µs/call # 17 times (226µs+0s) by base::import at line 74 of base.pm, avg 13µs/call # 7 times (44µs+0s) by XML::Simple::value_to_xml at line 1622 of XML/Simple.pm, avg 6µs/call # 5 times (227µs+0s) by XML::Simple::_get_object at line 162 of XML/Simple.pm, avg 45µs/call # once (8µs+0s) by XML::Simple::XMLout at line 603 of XML/Simple.pm # once (7µs+0s) by XML::Simple::XMLout at line 621 of XML/Simple.pm
sub UNIVERSAL::isa; # xsub
# spent 18µs within main::CORE:ftis which was called: # once (18µs+0s) by main::checkFile at line 244
sub main::CORE:ftis; # opcode
# spent 24µs within main::CORE:match which was called 3 times, avg 8µs/call: # once (11µs+0s) by main::RUNTIME at line 405 # once (7µs+0s) by main::RUNTIME at line 407 # once (6µs+0s) by main::RUNTIME at line 247
sub main::CORE:match; # opcode
# spent 661µs within main::CORE:subst which was called 87 times, avg 8µs/call: # 84 times (580µs+0s) by main::RUNTIME at line 380, avg 7µs/call # once (45µs+0s) by main::read_xml at line 316 # once (26µs+0s) by main::RUNTIME at line 261 # once (10µs+0s) by main::get_xml at line 286
sub main::CORE:subst; # opcode
# spent 80µs within main::CORE:substcont which was called 2 times, avg 40µs/call: # 2 times (80µs+0s) by main::read_xml at line 316, avg 40µs/call
sub main::CORE:substcont; # opcode
# spent 1.00ms within mro::method_changed_in which was called 92 times, avg 11µs/call: # 92 times (1.00ms+0s) by constant::import at line 162 of constant.pm, avg 11µs/call
sub mro::method_changed_in; # xsub
# spent 40µs within version::(bool which was called: # once (40µs+0s) by DynaLoader::BEGIN@22 at line 57 of Config.pm
sub version::(bool; # xsub
# spent 27µs within version::(cmp which was called: # once (27µs+0s) by DynaLoader::BEGIN@22 at line 60 of Config.pm
sub version::(cmp; # xsub