Skip to content

Commit 6aeaf75

Browse files
Merge pull request #124 from runcommand/61-eval-hook
Use `--hook[=<hook>]` to profile all hooks, or callbacks to spec hook
2 parents 3f8f06f + fd29f1b commit 6aeaf75

File tree

6 files changed

+93
-37
lines changed

6 files changed

+93
-37
lines changed

README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ will need to execute during the course of the request.
144144
Profile arbitrary code execution.
145145

146146
~~~
147-
wp profile eval <php-code> [--fields=<fields>] [--format=<format>]
147+
wp profile eval <php-code> [--hook[=<hook>]] [--fields=<fields>] [--format=<format>]
148148
~~~
149149

150150
Code execution happens after WordPress has loaded entirely, which means
@@ -156,6 +156,9 @@ current theme.
156156
<php-code>
157157
The code to execute, as a string.
158158

159+
[--hook[=<hook>]]
160+
Focus on key metrics for all hooks, or callbacks on a specific hook.
161+
159162
[--fields=<fields>]
160163
Display one or more fields.
161164

@@ -177,7 +180,7 @@ current theme.
177180
Profile execution of an arbitrary file.
178181

179182
~~~
180-
wp profile eval-file <file> [--fields=<fields>] [--format=<format>]
183+
wp profile eval-file <file> [--hook[=<hook>]] [--fields=<fields>] [--format=<format>]
181184
~~~
182185

183186
File execution happens after WordPress has loaded entirely, which means
@@ -189,6 +192,9 @@ current theme.
189192
<file>
190193
The path to the PHP file to execute and profile.
191194

195+
[--hook[=<hook>]]
196+
Focus on key metrics for all hooks, or callbacks on a specific hook.
197+
192198
[--fields=<fields>]
193199
Display one or more fields.
194200

features/profile-eval-file.feature

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,22 @@ Feature: Profile arbitary file execution
5353
Then STDOUT should be a table containing rows:
5454
| cache_hits | cache_misses |
5555
| 2 | 0 |
56+
57+
Scenario: Profile a function calling a hook
58+
Given a WP install
59+
And a calls-hook.php file:
60+
"""
61+
<?php
62+
add_filter( 'logout_url', function( $url ) { wp_cache_get( 'foo' ); return $url; });
63+
wp_logout_url();
64+
"""
65+
66+
When I run `wp profile eval-file calls-hook.php --hook --fields=hook,cache_hits,cache_misses`
67+
Then STDOUT should be a table containing rows:
68+
| hook | cache_hits | cache_misses |
69+
| logout_url | 0 | 1 |
70+
71+
When I run `wp profile eval-file calls-hook.php --hook=logout_url --fields=callback,cache_hits,cache_misses`
72+
Then STDOUT should be a table containing rows:
73+
| callback | cache_hits | cache_misses |
74+
| function(){} | 0 | 1 |

features/profile-eval.feature

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,16 @@ Feature: Profile arbitary code execution
3535
Then STDOUT should be a table containing rows:
3636
| cache_hits | cache_misses |
3737
| 2 | 0 |
38+
39+
Scenario: Profile a function calling a hook
40+
Given a WP install
41+
42+
When I run `wp profile eval "add_filter( 'logout_url', function( $url ) { wp_cache_get( 'foo' ); return $url; }); wp_logout_url();" --hook --fields=hook,cache_hits,cache_misses`
43+
Then STDOUT should be a table containing rows:
44+
| hook | cache_hits | cache_misses |
45+
| logout_url | 0 | 1 |
46+
47+
When I run `wp profile eval "add_filter( 'logout_url', function( $url ) { wp_cache_get( 'foo' ); return $url; }); wp_logout_url();" --hook=logout_url --fields=callback,cache_hits,cache_misses`
48+
Then STDOUT should be a table containing rows:
49+
| callback | cache_hits | cache_misses |
50+
| function(){} | 0 | 1 |

features/profile.feature

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ Feature: Basic profile usage
66
When I run `wp profile`
77
Then STDOUT should be:
88
"""
9-
usage: wp profile eval <php-code> [--fields=<fields>] [--format=<format>]
10-
or: wp profile eval-file <file> [--fields=<fields>] [--format=<format>]
9+
usage: wp profile eval <php-code> [--hook[=<hook>]] [--fields=<fields>] [--format=<format>]
10+
or: wp profile eval-file <file> [--hook[=<hook>]] [--fields=<fields>] [--format=<format>]
1111
or: wp profile hook [<hook>] [--all] [--spotlight] [--url=<url>] [--fields=<fields>] [--format=<format>]
1212
or: wp profile stage [<stage>] [--all] [--spotlight] [--url=<url>] [--fields=<fields>] [--format=<format>]
1313

inc/class-command.php

Lines changed: 46 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,9 @@ public function hook( $args, $assoc_args ) {
221221
* <php-code>
222222
* : The code to execute, as a string.
223223
*
224+
* [--hook[=<hook>]]
225+
* : Focus on key metrics for all hooks, or callbacks on a specific hook.
226+
*
224227
* [--fields=<fields>]
225228
* : Display one or more fields.
226229
*
@@ -235,31 +238,13 @@ public function hook( $args, $assoc_args ) {
235238
* - csv
236239
* ---
237240
*
238-
* @when before_wp_load
239241
* @subcommand eval
240242
*/
241243
public function eval_( $args, $assoc_args ) {
242-
243-
$profiler = new Profiler( false, false );
244-
$profiler->run();
245-
246-
$logger = new Logger();
247-
$logger->start();
248-
eval( $args[0] );
249-
$logger->stop();
250-
251-
$fields = array(
252-
'time',
253-
'query_time',
254-
'query_count',
255-
'cache_ratio',
256-
'cache_hits',
257-
'cache_misses',
258-
'request_time',
259-
'request_count',
260-
);
261-
$formatter = new Formatter( $assoc_args, $fields );
262-
$formatter->display_items( array( $logger ), false );
244+
$statement = $args[0];
245+
self::profile_eval_ish( $assoc_args, function() use ( $statement ) {
246+
eval( $statement );
247+
});
263248
}
264249

265250
/**
@@ -274,6 +259,9 @@ public function eval_( $args, $assoc_args ) {
274259
* <file>
275260
* : The path to the PHP file to execute and profile.
276261
*
262+
* [--hook[=<hook>]]
263+
* : Focus on key metrics for all hooks, or callbacks on a specific hook.
264+
*
277265
* [--fields=<fields>]
278266
* : Display one or more fields.
279267
*
@@ -288,7 +276,6 @@ public function eval_( $args, $assoc_args ) {
288276
* - csv
289277
* ---
290278
*
291-
* @when before_wp_load
292279
* @subcommand eval-file
293280
*/
294281
public function eval_file( $args, $assoc_args ) {
@@ -298,15 +285,41 @@ public function eval_file( $args, $assoc_args ) {
298285
WP_CLI::error( "'$file' does not exist." );
299286
}
300287

301-
$profiler = new Profiler( false, false );
302-
$profiler->run();
303-
304-
$logger = new Logger();
305-
$logger->start();
306-
self::include_file( $file );
307-
$logger->stop();
288+
self::profile_eval_ish( $assoc_args, function() use ( $file ) {
289+
self::include_file( $file );
290+
});
291+
}
308292

309-
$fields = array(
293+
/**
294+
* Profile an eval or eval-file statement.
295+
*/
296+
private static function profile_eval_ish( $assoc_args, $profile_callback ) {
297+
$hook = Utils\get_flag_value( $assoc_args, 'hook' );
298+
$type = $focus = false;
299+
$fields = array();
300+
if ( $hook ) {
301+
$type = 'hook';
302+
if ( true !== $hook ) {
303+
$focus = $hook;
304+
$fields[] = 'callback';
305+
$fields[] = 'location';
306+
} else {
307+
$fields[] = 'hook';
308+
}
309+
}
310+
$profiler = new Profiler( $type, $focus );
311+
$profiler->run();
312+
if ( $hook ) {
313+
$profile_callback();
314+
$loggers = $profiler->get_loggers();
315+
} else {
316+
$logger = new Logger();
317+
$logger->start();
318+
$profile_callback();
319+
$logger->stop();
320+
$loggers = array( $logger );
321+
}
322+
$fields = array_merge( $fields, array(
310323
'time',
311324
'query_time',
312325
'query_count',
@@ -315,9 +328,9 @@ public function eval_file( $args, $assoc_args ) {
315328
'cache_misses',
316329
'request_time',
317330
'request_count',
318-
);
331+
) );
319332
$formatter = new Formatter( $assoc_args, $fields );
320-
$formatter->display_items( array( $logger ), false );
333+
$formatter->display_items( $loggers, false );
321334
}
322335

323336
/**

inc/class-profiler.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,11 @@ public function wp_request_end( $filter_value = null ) {
370370
*/
371371
private function load_wordpress_with_template() {
372372

373+
// WordPress already ran once.
374+
if ( function_exists( 'add_filter' ) ) {
375+
return;
376+
}
377+
373378
if ( 'stage' === $this->type && true === $this->focus ) {
374379
$hooks = array();
375380
foreach( $this->stage_hooks as $stage_hook ) {

0 commit comments

Comments
 (0)