-
Notifications
You must be signed in to change notification settings - Fork 97
Create Abstract Check Runner & CLI_Runner classes #73
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
a341672
setup abstract check runner class
jjgrainger 967d77e
Merge branch 'trunk' into feature/create-abstract-check-runner
jjgrainger a2c7420
update get_shared_preparations method
jjgrainger 69b0d66
minor fixes
jjgrainger 0b0b4ae
simplify get_shared_preparations logic
jjgrainger a5e9f6e
replace properties with methods
jjgrainger fff26bc
update imports
jjgrainger 86d6930
update docblock comments
jjgrainger 319a8e0
create CLI_Runner class
jjgrainger bac30bb
add tests
jjgrainger b6ccecb
remove imports
jjgrainger b90860c
fix tests
jjgrainger 63de1b3
remove get_context method
jjgrainger 24e0d58
update checks methods
jjgrainger 151ba82
create Plugin_Request_Utility class
jjgrainger a0b32c0
update checks
jjgrainger 9626911
Merge branch 'trunk' into feature/create-abstract-check-runner
jjgrainger ee26850
update comments and exception messages
jjgrainger 011c8a4
update tests
jjgrainger 69a52ad
Merge branch 'trunk' into feature/create-abstract-check-runner
jjgrainger File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,160 @@ | ||
| <?php | ||
| /** | ||
| * Class WordPress\Plugin_Check\Checker\Abstract_Check_runner | ||
| * | ||
| * @package plugin-check | ||
| */ | ||
|
|
||
| namespace WordPress\Plugin_Check\Checker; | ||
|
|
||
| use WordPress\Plugin_Check\Checker\Preparations\Universal_Runtime_Preparation; | ||
|
|
||
| /** | ||
| * Abstract Check Runner class. | ||
| * | ||
| * @since n.e.x.t | ||
| */ | ||
| abstract class Abstract_Check_Runner implements Check_Runner { | ||
|
|
||
| /** | ||
| * Determines if the current request is intended for the plugin checker. | ||
| * | ||
| * @since n.e.x.t | ||
| * | ||
| * @return bool Returns true if the check is for plugin else false. | ||
| */ | ||
| abstract public function is_plugin_check(); | ||
|
|
||
| /** | ||
| * Creates and returns an instance of the Checks class based on the request. | ||
| * | ||
| * @since n.e.x.t | ||
| * | ||
| * @return Checks An instances of the Checks class. | ||
| */ | ||
| abstract protected function get_checks_instance(); | ||
|
|
||
| /** | ||
| * Returns an array of Check slugs to run based on the request. | ||
| * | ||
| * @since n.e.x.t | ||
| * | ||
| * @return array An array of Check slugs. | ||
| */ | ||
|
jjgrainger marked this conversation as resolved.
|
||
| abstract protected function get_check_slugs_to_run(); | ||
|
|
||
| /** | ||
| * Prepares the environment for running the requested checks. | ||
| * | ||
| * @since n.e.x.t | ||
| * | ||
| * @return callable Cleanup function to revert any changes made here. | ||
| * | ||
| * @throws Exception Thrown exception when preparation fails. | ||
| */ | ||
| public function prepare() { | ||
| if ( $this->requires_universal_preparations( $this->get_checks_to_run() ) ) { | ||
| $preparation = new Universal_Runtime_Preparation( $this->get_checks_instance()->context() ); | ||
| return $preparation->prepare(); | ||
| } | ||
|
|
||
| return function() {}; | ||
| } | ||
|
|
||
| /** | ||
| * Runs the checks against the plugin. | ||
| * | ||
| * @since n.e.x.t | ||
| * | ||
| * @return Check_Result An object containing all check results. | ||
| */ | ||
| public function run() { | ||
| $checks = $this->get_checks_to_run(); | ||
| $preparations = $this->get_shared_preparations( $checks ); | ||
| $cleanups = array(); | ||
|
|
||
| foreach ( $preparations as $preparation ) { | ||
| $instance = new $preparation['class']( ...$preparation['args'] ); | ||
| $cleanups[] = $instance->prepare(); | ||
| } | ||
|
|
||
| $results = $this->get_checks_instance()->run_checks( $checks ); | ||
|
|
||
| if ( ! empty( $cleanups ) ) { | ||
| foreach ( $cleanups as $cleanup ) { | ||
| $cleanup(); | ||
| } | ||
| } | ||
|
|
||
| return $results; | ||
| } | ||
|
|
||
| /** | ||
| * Determines if any of the checks requires the universal runtime preparation. | ||
| * | ||
| * @since n.e.x.t | ||
| * | ||
| * @param array $checks An array of check instances to run. | ||
| * @return bool Returns true if one or more checks requires the universal runtime preparation. | ||
| */ | ||
| protected function requires_universal_preparations( array $checks ) { | ||
| foreach ( $checks as $check ) { | ||
| if ( $check instanceof Runtime_Check ) { | ||
| return true; | ||
| } | ||
| } | ||
|
|
||
| return false; | ||
| } | ||
|
|
||
| /** | ||
| * Returns all shared preparations used by the checks to run. | ||
| * | ||
| * @since n.e.x.t | ||
| * | ||
| * @param array $checks An array of Check instances to run. | ||
| * @return array An array of Preparations to run where each item is an array with keys `class` and `args`. | ||
| */ | ||
| private function get_shared_preparations( array $checks ) { | ||
| $shared_preparations = array(); | ||
|
|
||
| foreach ( $checks as $check ) { | ||
| if ( ! $check instanceof With_Shared_Preparations ) { | ||
| continue; | ||
| } | ||
|
|
||
| $preparations = $check->get_shared_preparations(); | ||
|
|
||
| foreach ( $preparations as $class => $args ) { | ||
| $key = $class . '::' . md5( json_encode( $args ) ); | ||
|
|
||
| if ( ! isset( $shared_preparations[ $key ] ) ) { | ||
| $shared_preparations[ $key ] = array( | ||
| 'class' => $class, | ||
| 'args' => $args, | ||
| ); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return array_values( $shared_preparations ); | ||
| } | ||
|
|
||
| /** | ||
| * Returns the Check instances to run. | ||
| * | ||
| * @since n.e.x.t | ||
| * | ||
| * @return array An array map of check slugs to Check instances. | ||
| */ | ||
| protected function get_checks_to_run() { | ||
| $check_slugs = $this->get_check_slugs_to_run(); | ||
| $all_checks = $this->get_checks_instance()->get_checks(); | ||
|
|
||
| if ( empty( $check_slugs ) ) { | ||
| return $all_checks; | ||
| } | ||
|
|
||
| return array_intersect_key( $all_checks, array_flip( $check_slugs ) ); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,90 @@ | ||
| <?php | ||
| /** | ||
| * Class WordPress\Plugin_Check\Checker\CLI_Runner | ||
| * | ||
| * @package plugin-check | ||
| */ | ||
|
|
||
| namespace WordPress\Plugin_Check\Checker; | ||
|
|
||
| use WordPress\Plugin_Check\Utilities\Plugin_Request_Utility; | ||
|
|
||
| /** | ||
| * CLI Runner class. | ||
| * | ||
| * @since n.e.x.t | ||
| */ | ||
| class CLI_Runner extends Abstract_Check_Runner { | ||
|
|
||
| /** | ||
| * An instances of the Checks class. | ||
| * | ||
| * @since n.e.x.t | ||
| * @var Checks | ||
| */ | ||
| protected $checks; | ||
|
|
||
| /** | ||
| * Checks if the current request is a CLI request for the Plugin Checker. | ||
| * | ||
| * @since n.e.x.t | ||
| * | ||
| * @return bool | ||
| */ | ||
| public function is_plugin_check() { | ||
| if ( empty( $_SERVER['argv'] ) || 3 > count( $_SERVER['argv'] ) ) { | ||
| return false; | ||
| } | ||
|
|
||
| if ( | ||
| 'wp' === $_SERVER['argv'][0] && | ||
| 'plugin' === $_SERVER['argv'][1] && | ||
| 'check' === $_SERVER['argv'][2] | ||
|
jjgrainger marked this conversation as resolved.
|
||
| ) { | ||
| return true; | ||
| } | ||
|
|
||
| return false; | ||
| } | ||
|
|
||
| /** | ||
| * Retruns an instance of the Checks class. | ||
| * | ||
| * @since n.e.x.t | ||
| * | ||
| * @return Checks | ||
| * | ||
| * @throws Exception Thrown if the plugin main file cannot be found based on the CLI input. | ||
| */ | ||
| protected function get_checks_instance() { | ||
| if ( ! isset( $this->checks ) ) { | ||
| // Get the plugin name from the command line arguments. | ||
| $plugin_slug = isset( $_SERVER['argv'][3] ) ? $_SERVER['argv'][3] : ''; | ||
| $plugin_file = Plugin_Request_Utility::get_plugin_basename_from_input( $plugin_slug ); | ||
|
|
||
| $this->checks = new Checks( WP_PLUGIN_DIR . '/' . $plugin_file ); | ||
| } | ||
|
|
||
| return $this->checks; | ||
| } | ||
|
jjgrainger marked this conversation as resolved.
|
||
|
|
||
| /** | ||
| * Returns an array of Check instances to run. | ||
| * | ||
| * @since n.e.x.t | ||
| * | ||
| * @return array An array of Check instances to run. | ||
| */ | ||
| protected function get_check_slugs_to_run() { | ||
| $checks = array(); | ||
|
|
||
| foreach ( $_SERVER['argv'] as $value ) { | ||
| if ( false !== strpos( $value, '--checks=' ) ) { | ||
| $checks = explode( ',', str_replace( '--checks=', '', $value ) ); | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| return $checks; | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| <?php | ||
| /** | ||
| * Class WordPress\Plugin_Check\Utilities | ||
| * | ||
| * @package plugin-check | ||
| */ | ||
|
|
||
| namespace WordPress\Plugin_Check\Utilities; | ||
|
|
||
| use Exception; | ||
|
|
||
| /** | ||
| * Class providing utility methods to return plugin information based on the request. | ||
| * | ||
| * @since n.e.x.t | ||
| */ | ||
| class Plugin_Request_Utility { | ||
|
|
||
| /** | ||
| * Returns the plugin basename based on the input provided. | ||
| * | ||
| * @param string $plugin_slug The plugin slug or basename. | ||
| * @return string The plugin basename. | ||
| * | ||
| * @throws Exception Thrown if an invalid basename or plugin slug is provided. | ||
| */ | ||
| public static function get_plugin_basename_from_input( $plugin_slug ) { | ||
| require_once ABSPATH . 'wp-admin/includes/plugin.php'; | ||
|
|
||
| if ( empty( $plugin_slug ) ) { | ||
| throw new Exception( 'Invalid plugin slug: Plugin slug must not be empty.' ); | ||
| } | ||
|
|
||
| $plugins = get_plugins(); | ||
|
|
||
| // Is the provided value is a full plugin basename? | ||
| if ( isset( $plugins[ $plugin_slug ] ) ) { | ||
| return $plugin_slug; | ||
| } | ||
|
|
||
| if ( strpos( $plugin_slug, '/' ) ) { | ||
| throw new Exception( | ||
| sprintf( | ||
| 'Invalid plugin basename: Plugin with basename %s is not installed.', | ||
| $plugin_slug | ||
| ) | ||
| ); | ||
| } | ||
|
|
||
| foreach ( $plugins as $plugin_basename => $plugin_data ) { | ||
| if ( strpos( $plugin_basename, $plugin_slug . '/' ) === 0 ) { | ||
| return $plugin_basename; | ||
| } | ||
| } | ||
|
|
||
| throw new Exception( | ||
| sprintf( | ||
| 'Invalid plugin slug: Plugin with slug %s is not installed.', | ||
| $plugin_slug | ||
| ) | ||
| ); | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.