Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions docs/CLI.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ By default, `.git`, `vendor`, `vendor_prefixed`, `vendor-prefixed` and `node_mod
[--exclude-files=<files>]
: Additional files to exclude from checks.

[--include-files=<files>]
: Specific files to include in checks (comma-separated). Mutually exclusive with --exclude-files.
: When specified, only the listed files will be checked.

[--include-directories=<directories>]
: Specific directories to include in checks (comma-separated, recursive). Mutually exclusive with --exclude-directories.
: When specified, only files within the listed directories will be checked.

[--severity=<severity>]
: Severity level.

Expand Down Expand Up @@ -87,6 +95,9 @@ wp plugin check akismet
wp plugin check akismet --checks=late_escaping
wp plugin check akismet --format=json
wp plugin check akismet --mode=update
wp plugin check akismet --include-files=akismet.php,class.akismet.php
wp plugin check akismet --include-directories=includes,views
wp plugin check akismet --exclude-directories=tests,vendor
```

# wp plugin list-checks
Expand Down
8 changes: 8 additions & 0 deletions includes/Admin/Admin_AJAX.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,14 @@ private function configure_runner( $runner ) {
$runner->set_check_slugs( $checks );
$runner->set_plugin( $plugin );

// Load configuration filters (e.g. .distignore, .plugin-check.json).
if ( ! empty( $plugin ) ) {
$plugin_path = WP_PLUGIN_DIR . '/' . basename( $plugin );
if ( is_dir( $plugin_path ) ) {
Plugin_Request_Utility::load_filters_from_config( $plugin_path );
}
}

return array(
'checks' => $checks,
'plugin' => $plugin,
Expand Down
75 changes: 70 additions & 5 deletions includes/CLI/Plugin_Check_Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,14 @@ public function __construct( Plugin_Context $plugin_context ) {
* [--exclude-files=<files>]
* : Additional files to exclude from checks.
*
* [--include-files=<files>]
* : Specific files to include in checks (comma-separated). Mutually exclusive with --exclude-files.
* When specified, only the listed files will be checked.
*
* [--include-directories=<directories>]
* : Specific directories to include in checks (comma-separated, recursive). Mutually exclusive with --exclude-directories.
* When specified, only files within the listed directories will be checked.
*
* [--severity=<severity>]
* : Severity level.
*
Expand Down Expand Up @@ -145,6 +153,9 @@ public function __construct( Plugin_Context $plugin_context ) {
* wp plugin check akismet --checks=late_escaping
* wp plugin check akismet --format=json
* wp plugin check akismet --mode=update
* wp plugin check akismet --include-files=akismet.php,class.akismet.php
* wp plugin check akismet --include-directories=includes,views
* wp plugin check akismet --exclude-directories=tests,vendor
*
* @subcommand check
*
Expand All @@ -160,9 +171,27 @@ public function __construct( Plugin_Context $plugin_context ) {
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
public function check( $args, $assoc_args ) {
// Get options based on the CLI arguments.
$options = $this->get_options(
$assoc_args,
$plugin = isset( $args[0] ) ? $args[0] : '';
$config = array();

if ( ! empty( $plugin ) ) {
$plugin_path = '';
if ( is_dir( $plugin ) ) {
$plugin_path = $plugin;
} elseif ( is_file( $plugin ) ) {
$plugin_path = dirname( $plugin );
} elseif ( ! filter_var( $plugin, FILTER_VALIDATE_URL ) ) {
// Assume slug for installed plugin.
$plugin_path = WP_PLUGIN_DIR . '/' . $plugin;
}

if ( ! empty( $plugin_path ) && is_dir( $plugin_path ) ) {
$config = Plugin_Request_Utility::get_plugin_configuration( $plugin_path );
Plugin_Request_Utility::load_distignore_filters( $plugin_path );
}
}

$defaults = array_merge(
array(
'checks' => '',
'format' => 'table',
Expand All @@ -177,11 +206,15 @@ public function check( $args, $assoc_args ) {
'slug' => '',
'ignore-codes' => '',
'mode' => 'new',
)
),
$config
);

// Get options based on the CLI arguments.
$options = $this->get_options( $assoc_args, $defaults );

// Create the plugin and checks array from CLI arguments.
$plugin = isset( $args[0] ) ? $args[0] : '';
// $plugin is already set above.
$checks = wp_parse_list( $options['checks'] );

// Ignore codes.
Expand All @@ -191,6 +224,14 @@ public function check( $args, $assoc_args ) {
$categories = isset( $options['categories'] ) ? wp_parse_list( $options['categories'] ) : array();

$excluded_directories = isset( $options['exclude-directories'] ) ? wp_parse_list( $options['exclude-directories'] ) : array();
$included_directories = isset( $options['include-directories'] ) ? wp_parse_list( $options['include-directories'] ) : array();

// Validate mutual exclusivity for directories.
if ( ! empty( $excluded_directories ) && ! empty( $included_directories ) ) {
WP_CLI::error(
__( 'The --include-directories and --exclude-directories options are mutually exclusive. Please use only one.', 'plugin-check' )
);
}

add_filter(
'wp_plugin_check_ignore_directories',
Expand All @@ -199,7 +240,22 @@ static function ( $dirs ) use ( $excluded_directories ) {
}
);

add_filter(
'wp_plugin_check_include_directories',
static function ( $dirs ) use ( $included_directories ) {
return array_unique( array_merge( $dirs, $included_directories ) );
}
);

$excluded_files = isset( $options['exclude-files'] ) ? wp_parse_list( $options['exclude-files'] ) : array();
$included_files = isset( $options['include-files'] ) ? wp_parse_list( $options['include-files'] ) : array();

// Validate mutual exclusivity for files.
if ( ! empty( $excluded_files ) && ! empty( $included_files ) ) {
WP_CLI::error(
__( 'The --include-files and --exclude-files options are mutually exclusive. Please use only one.', 'plugin-check' )
);
}

add_filter(
'wp_plugin_check_ignore_files',
Expand All @@ -208,6 +264,15 @@ static function ( $dirs ) use ( $excluded_files ) {
}
);

add_filter(
'wp_plugin_check_include_files',
static function ( $dirs ) use ( $included_files ) {
return array_unique( array_merge( $dirs, $included_files ) );
}
);



Comment on lines +274 to +275
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

// Get the CLI Runner.
$runner = Plugin_Request_Utility::get_runner();

Expand Down
37 changes: 37 additions & 0 deletions includes/Checker/Checks/Abstract_File_Check.php
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,9 @@ private static function get_files( Check_Context $plugin ) {
$directories_to_ignore = Plugin_Request_Utility::get_directories_to_ignore();

$files_to_ignore = Plugin_Request_Utility::get_files_to_ignore();
$directories_to_include = Plugin_Request_Utility::get_directories_to_include();
$files_to_include = Plugin_Request_Utility::get_files_to_include();
$ignore_patterns = Plugin_Request_Utility::get_files_to_ignore_patterns();

foreach ( $iterator as $file ) {
if ( ! $file->isFile() ) {
Expand All @@ -296,6 +299,30 @@ private static function get_files( Check_Context $plugin ) {
// Flag to check if the file should be included or not.
$include_file = true;

if ( ! empty( $directories_to_include ) || ! empty( $files_to_include ) ) {
$include_file = false;

foreach ( $directories_to_include as $directory ) {
if ( false !== strpos( $file_path, '/' . $directory . '/' ) ) {
$include_file = true;
break;
}
}

if ( ! $include_file ) {
foreach ( $files_to_include as $inc_file ) {
if ( str_ends_with( $file_path, "/" . $inc_file ) ) {
$include_file = true;
break;
}
}
}

if ( ! $include_file ) {
continue;
}
}

foreach ( $directories_to_ignore as $directory ) {
// Check if the current file belongs to the directory you want to ignore.
if ( false !== strpos( $file_path, '/' . $directory . '/' ) ) {
Expand All @@ -311,6 +338,16 @@ private static function get_files( Check_Context $plugin ) {
}
}

if ( $include_file && ! empty( $ignore_patterns ) ) {
$relative_path = substr( $file_path, strlen( $location ) + 1 );
foreach ( $ignore_patterns as $pattern ) {
if ( preg_match( $pattern, $relative_path ) ) {
$include_file = false;
break;
}
}
}

if ( $include_file ) {
self::$file_list_cache[ $location ][] = $file_path;
}
Expand Down
Loading
Loading