Skip to content

Commit

Permalink
Add amp analyze CLI command
Browse files Browse the repository at this point in the history
  • Loading branch information
ediamin authored and schlessera committed Dec 19, 2021
1 parent 09c9f09 commit c553246
Show file tree
Hide file tree
Showing 3 changed files with 274 additions and 0 deletions.
1 change: 1 addition & 0 deletions .phpstorm.meta.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
'admin.validation_counts' => \AmpProject\AmpWP\Admin\ValidationCounts::class,
'amp_slug_customization_watcher' => \AmpProject\AmpWP\AmpSlugCustomizationWatcher::class,
'background_task_deactivator' => \AmpProject\AmpWP\BackgroundTask\BackgroundTaskDeactivator::class,
'cli.analyze_command' => \AmpProject\AmpWP\Cli\AnalyzeCommand::class,
'cli.command_namespace' => \AmpProject\AmpWP\CliCli\CommandNamespaceRegistration::class,
'cli.optimizer_command' => \AmpProject\AmpWP\CliCli\OptimizerCommand::class,
'cli.transformer_command' => \AmpProject\AmpWP\CliCli\TransformerCommand::class,
Expand Down
1 change: 1 addition & 0 deletions src/AmpWpPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ final class AmpWpPlugin extends ServiceBasedPlugin {
'admin.amp_themes' => Admin\AmpThemes::class,
'amp_slug_customization_watcher' => AmpSlugCustomizationWatcher::class,
'background_task_deactivator' => BackgroundTaskDeactivator::class,
'cli.analyze_command' => Cli\AnalyzeCommand::class,
'cli.command_namespace' => Cli\CommandNamespaceRegistration::class,
'cli.optimizer_command' => Cli\OptimizerCommand::class,
'cli.transformer_command' => Cli\TransformerCommand::class,
Expand Down
272 changes: 272 additions & 0 deletions src/Cli/AnalyzeCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,272 @@
<?php
/**
* Class AnalyzeCommand.
*
* Commands that deal with analyze an URL against the PX Engine.
*
* @package AmpProject\AmpWP
*/

namespace AmpProject\AmpWP\Cli;

use AmpProject\AmpWP\Infrastructure\CliCommand;
use AmpProject\AmpWP\Infrastructure\Service;
use AmpProject\AmpWP\RemoteRequest\CachedRemoteGetRequest;
use AmpProject\AmpWP\RemoteRequest\WpHttpRemoteGetRequest;
use AmpProject\AmpWP\Validation\ScannableURLProvider;
use PageExperience\Engine;
use PageExperience\Engine\Analysis\Issue;
use PageExperience\Engine\ConfigurationProfile;
use WP_CLI;
use WP_CLI\Formatter;

/**
* Analyze site URLs with Page Experience Engine.
*
* @internal
*/
final class AnalyzeCommand implements Service, CliCommand {

/**
* The WP CLI progress bar.
*
* @var \cli\progress\Bar|\WP_CLI\NoOp
*/
public $wp_cli_progress;

/**
* ScannableURLProvider instance.
*
* @var ScannableURLProvider
*/
private $scannable_url_provider;

/**
* Get the name under which to register the CLI command.
*
* @return string The name under which to register the CLI command.
*/
public static function get_command_name() {
return 'amp';
}

Check warning on line 51 in src/Cli/AnalyzeCommand.php

View check run for this annotation

Codecov / codecov/patch

src/Cli/AnalyzeCommand.php#L49-L51

Added lines #L49 - L51 were not covered by tests

/**
* Construct.
*
* @param ScannableURLProvider $scannable_url_provider Scannable URL provider.
*/
public function __construct( ScannableURLProvider $scannable_url_provider ) {
$this->scannable_url_provider = $scannable_url_provider;
}

Check warning on line 60 in src/Cli/AnalyzeCommand.php

View check run for this annotation

Codecov / codecov/patch

src/Cli/AnalyzeCommand.php#L58-L60

Added lines #L58 - L60 were not covered by tests

/**
* Analyze site URLs with Page Experience Engine.
*
* [<url>]
* : URL to analyze.
*
* ## OPTIONS
*
* [--timeout=<timeout_in_seconds>]
* : Timeout value to use in seconds.
* ---
* default: 5
* ---
*
* [--format=<format>]
* : Render output in a particular format.
* ---
* default: table
* options:
* - count
* - csv
* - json
* - table
* - yaml
* ---
*
* ## EXAMPLES
*
* # Analyze all site URLs.
* $ wp amp analyze --timeout=20
*
* # Analyze a specific URL.
* $ wp amp analyze http://example.com
*
* @param array $urls URLs to analyze.
* @param array $assoc_args Associative args.
*/
public function analyze( $urls = [], $assoc_args ) {
if ( ! is_array( $urls ) || empty( $urls ) ) {
$urls = $this->scannable_url_provider->get_urls();
}

Check warning on line 102 in src/Cli/AnalyzeCommand.php

View check run for this annotation

Codecov / codecov/patch

src/Cli/AnalyzeCommand.php#L99-L102

Added lines #L99 - L102 were not covered by tests

$number_of_urls = count( $urls );

Check warning on line 104 in src/Cli/AnalyzeCommand.php

View check run for this annotation

Codecov / codecov/patch

src/Cli/AnalyzeCommand.php#L104

Added line #L104 was not covered by tests

$assoc_args = wp_parse_args(
$assoc_args,
[
'timeout' => WpHttpRemoteGetRequest::DEFAULT_TIMEOUT,
'format' => 'table',
]
);

Check warning on line 112 in src/Cli/AnalyzeCommand.php

View check run for this annotation

Codecov / codecov/patch

src/Cli/AnalyzeCommand.php#L106-L112

Added lines #L106 - L112 were not covered by tests

WP_CLI::log( 'Analyzing Page Experience.' );

Check warning on line 114 in src/Cli/AnalyzeCommand.php

View check run for this annotation

Codecov / codecov/patch

src/Cli/AnalyzeCommand.php#L114

Added line #L114 was not covered by tests

$this->wp_cli_progress = WP_CLI\Utils\make_progress_bar(
sprintf( 'Analyzing %d URLs...', $number_of_urls ),
$number_of_urls
);

Check warning on line 119 in src/Cli/AnalyzeCommand.php

View check run for this annotation

Codecov / codecov/patch

src/Cli/AnalyzeCommand.php#L116-L119

Added lines #L116 - L119 were not covered by tests

$results = [];
$failed_urls = [];

Check warning on line 122 in src/Cli/AnalyzeCommand.php

View check run for this annotation

Codecov / codecov/patch

src/Cli/AnalyzeCommand.php#L121-L122

Added lines #L121 - L122 were not covered by tests

$this->wp_cli_progress->display();

Check warning on line 124 in src/Cli/AnalyzeCommand.php

View check run for this annotation

Codecov / codecov/patch

src/Cli/AnalyzeCommand.php#L124

Added line #L124 was not covered by tests

foreach ( $urls as $url ) {
$url = isset( $url['url'] ) ? $url['url'] : $url;

Check warning on line 127 in src/Cli/AnalyzeCommand.php

View check run for this annotation

Codecov / codecov/patch

src/Cli/AnalyzeCommand.php#L126-L127

Added lines #L126 - L127 were not covered by tests

try {
$results[ $url ] = $this->get_analysis_results(
$url,
absint( $assoc_args['timeout'] )
);
} catch ( \Exception $error ) {
$failed_urls[] = [
'URL' => $url,
'Message' => $error->getMessage(),
];
}

Check warning on line 139 in src/Cli/AnalyzeCommand.php

View check run for this annotation

Codecov / codecov/patch

src/Cli/AnalyzeCommand.php#L129-L139

Added lines #L129 - L139 were not covered by tests

if ( $this->wp_cli_progress ) {
$this->wp_cli_progress->tick();
}
}

Check warning on line 144 in src/Cli/AnalyzeCommand.php

View check run for this annotation

Codecov / codecov/patch

src/Cli/AnalyzeCommand.php#L141-L144

Added lines #L141 - L144 were not covered by tests

$this->wp_cli_progress->finish();

Check warning on line 146 in src/Cli/AnalyzeCommand.php

View check run for this annotation

Codecov / codecov/patch

src/Cli/AnalyzeCommand.php#L146

Added line #L146 was not covered by tests

if ( ! empty( $results ) ) {
WP_CLI::line();
WP_CLI::line( 'Analyzed URLs:' );
$this->print_metrics( $results, $assoc_args );
}

Check warning on line 152 in src/Cli/AnalyzeCommand.php

View check run for this annotation

Codecov / codecov/patch

src/Cli/AnalyzeCommand.php#L148-L152

Added lines #L148 - L152 were not covered by tests

if ( ! empty( $failed_urls ) ) {
WP_CLI::line();
WP_CLI::line( 'URLs failed to analyze:' );
WP_CLI\Utils\format_items( $assoc_args['format'], $failed_urls, [ 'URL' ] );
}
}

Check warning on line 159 in src/Cli/AnalyzeCommand.php

View check run for this annotation

Codecov / codecov/patch

src/Cli/AnalyzeCommand.php#L154-L159

Added lines #L154 - L159 were not covered by tests

/**
* Get URL analysis result.
*
* @param string $url The URL to analyze.
* @param int $timeout Timeout value to use in seconds.
*/
private function get_analysis_results( $url, $timeout ) {
$remote_request = new CachedRemoteGetRequest( new WpHttpRemoteGetRequest( true, $timeout ) );
$engine = new Engine( $remote_request );
$profile = new ConfigurationProfile();
$analysis = $engine->analyze( $url, $profile );

Check warning on line 171 in src/Cli/AnalyzeCommand.php

View check run for this annotation

Codecov / codecov/patch

src/Cli/AnalyzeCommand.php#L167-L171

Added lines #L167 - L171 were not covered by tests

return $analysis->getResults();
}

Check warning on line 174 in src/Cli/AnalyzeCommand.php

View check run for this annotation

Codecov / codecov/patch

src/Cli/AnalyzeCommand.php#L173-L174

Added lines #L173 - L174 were not covered by tests

/**
* Print PageSpeed Insight metrics.
*
* @param array $results Analysis results.
* @param array $assoc_args Associative args.
*/
private function print_metrics( $results, $assoc_args ) {
$table_data = [];
$home_url = home_url();

Check warning on line 184 in src/Cli/AnalyzeCommand.php

View check run for this annotation

Codecov / codecov/patch

src/Cli/AnalyzeCommand.php#L182-L184

Added lines #L182 - L184 were not covered by tests

foreach ( $results as $url => $result ) {
$table_data[] = [
'URL' => str_replace( $home_url, '', $url ),
'Metrics' => $this->get_metrics( $result['first-contentful-paint'], $assoc_args ),
];

Check warning on line 190 in src/Cli/AnalyzeCommand.php

View check run for this annotation

Codecov / codecov/patch

src/Cli/AnalyzeCommand.php#L186-L190

Added lines #L186 - L190 were not covered by tests

$table_data[] = [
'URL' => '',
'Metrics' => $this->get_metrics( $result['interactive'], $assoc_args ),
];

Check warning on line 195 in src/Cli/AnalyzeCommand.php

View check run for this annotation

Codecov / codecov/patch

src/Cli/AnalyzeCommand.php#L192-L195

Added lines #L192 - L195 were not covered by tests

$table_data[] = [
'URL' => '',
'Metrics' => $this->get_metrics( $result['speed-index'], $assoc_args ),
];

Check warning on line 200 in src/Cli/AnalyzeCommand.php

View check run for this annotation

Codecov / codecov/patch

src/Cli/AnalyzeCommand.php#L197-L200

Added lines #L197 - L200 were not covered by tests

$table_data[] = [
'URL' => '',
'Metrics' => $this->get_metrics( $result['total-blocking-time'], $assoc_args ),
];

Check warning on line 205 in src/Cli/AnalyzeCommand.php

View check run for this annotation

Codecov / codecov/patch

src/Cli/AnalyzeCommand.php#L202-L205

Added lines #L202 - L205 were not covered by tests

$table_data[] = [
'URL' => '',
'Metrics' => $this->get_metrics( $result['largest-contentful-paint'], $assoc_args ),
];

Check warning on line 210 in src/Cli/AnalyzeCommand.php

View check run for this annotation

Codecov / codecov/patch

src/Cli/AnalyzeCommand.php#L207-L210

Added lines #L207 - L210 were not covered by tests

$table_data[] = [
'URL' => '',
'Metrics' => $this->get_metrics( $result['cumulative-layout-shift'], $assoc_args ),
];

Check warning on line 215 in src/Cli/AnalyzeCommand.php

View check run for this annotation

Codecov / codecov/patch

src/Cli/AnalyzeCommand.php#L212-L215

Added lines #L212 - L215 were not covered by tests

$table_data[] = [
'URL' => '',
'Metrics' => '',
];
}

Check warning on line 221 in src/Cli/AnalyzeCommand.php

View check run for this annotation

Codecov / codecov/patch

src/Cli/AnalyzeCommand.php#L217-L221

Added lines #L217 - L221 were not covered by tests

$args = [
'format' => $assoc_args['format'],
'fields' => [ 'URL', 'Metrics' ],
];
$formatter = new Formatter( $args );
$formatter->display_items( $table_data, true );
}

Check warning on line 229 in src/Cli/AnalyzeCommand.php

View check run for this annotation

Codecov / codecov/patch

src/Cli/AnalyzeCommand.php#L223-L229

Added lines #L223 - L229 were not covered by tests

/**
* Get insight metrics.
*
* @param Issue $issue Result entry of an analysis for a URL.
* @param array $assoc_args Associative args.
*/
private function get_metrics( Issue $issue, $assoc_args ) {
$score = $issue->getScore();
$value = $issue->getDisplayValue();

Check warning on line 239 in src/Cli/AnalyzeCommand.php

View check run for this annotation

Codecov / codecov/patch

src/Cli/AnalyzeCommand.php#L237-L239

Added lines #L237 - L239 were not covered by tests

$icon = '';
$color_token = '';

Check warning on line 242 in src/Cli/AnalyzeCommand.php

View check run for this annotation

Codecov / codecov/patch

src/Cli/AnalyzeCommand.php#L241-L242

Added lines #L241 - L242 were not covered by tests

if ( $score >= 0.9 ) {
$icon = '';
$color_token = '%g';
} elseif ( $score >= 0.5 ) {
$icon = '';
$color_token = '%y';
} else {
$icon = '';
$color_token = '%r';
}

Check warning on line 253 in src/Cli/AnalyzeCommand.php

View check run for this annotation

Codecov / codecov/patch

src/Cli/AnalyzeCommand.php#L244-L253

Added lines #L244 - L253 were not covered by tests

if ( 'table' === $assoc_args['format'] ) {
$icon = $this->colorize( $icon, $color_token );
$value = $this->colorize( $value, $color_token );
}

Check warning on line 258 in src/Cli/AnalyzeCommand.php

View check run for this annotation

Codecov / codecov/patch

src/Cli/AnalyzeCommand.php#L255-L258

Added lines #L255 - L258 were not covered by tests

return $icon . ' ' . $issue->getLabel() . ': ' . $value;
}

Check warning on line 261 in src/Cli/AnalyzeCommand.php

View check run for this annotation

Codecov / codecov/patch

src/Cli/AnalyzeCommand.php#L260-L261

Added lines #L260 - L261 were not covered by tests

/**
* Colorize a string.
*
* @param string $string String to colorize for output.
* @param string $color_token Color token to colorize with.
*/
private function colorize( $string, $color_token ) {
return WP_CLI::colorize( $color_token . $string . '%n' );
}

Check warning on line 271 in src/Cli/AnalyzeCommand.php

View check run for this annotation

Codecov / codecov/patch

src/Cli/AnalyzeCommand.php#L269-L271

Added lines #L269 - L271 were not covered by tests
}

0 comments on commit c553246

Please sign in to comment.