Skip to content

Commit

Permalink
Merge pull request #285 from Automattic/fix/phpcs-ignore-standard
Browse files Browse the repository at this point in the history
Add support for ignoring PHPCS standards during startup
  • Loading branch information
gudmdharalds authored Jul 6, 2022
2 parents 84d9a7e + 9064bbf commit 36cb4d9
Show file tree
Hide file tree
Showing 7 changed files with 329 additions and 25 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,8 @@ Any number of PHPCS standards can be specified, and any number of runtime settin

To use a different PHP interpreter than the system default to run PHPCS, use `--phpcs-php-path`. This should point to a PHP binary.

PHPCS standards can be ignored while searching for PHPCS standards and sniffs during startup by using the `--phpcs-standards-to-ignore` parameter. This is useful for example when a PHPCS standard available does not implement any sniffs, which can cause PHPCS to exit with error when asked to provide sniffs for such a standard. Sniffs implemented by ignored PHPCS standards are not available via `--phpcs-sniffs-include` or `--phpcs-sniffs-exclude` (unless they are included by other PHPCS standards available) and `vip-go-ci` will not attempt to search for sniffs implemented by ignored PHPCS standards.

The following PHPCS-related options can be configured via repository config-file:

#### Options `--phpcs` and `--phpcs-severity`
Expand Down
1 change: 1 addition & 0 deletions log.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ function vipgoci_sysexit(
( vipgoci_unittests_check_indication_for_test_id( 'MainRunScanSkipExecutionTest' ) ) ||
( vipgoci_unittests_check_indication_for_test_id( 'MainRunScanMaxExecTimeTest' ) ) ||
( vipgoci_unittests_check_indication_for_test_id( 'MainRunInitGithubTokenOptionTest' ) ) ||
( vipgoci_unittests_check_indication_for_test_id( 'MainRunInitOptionsPhpcsTest' ) ) ||
( vipgoci_unittests_check_indication_for_test_id( 'OtherWebServicesIrcApiFilterIgnorableStringsTest' ) ) ||
( vipgoci_unittests_check_indication_for_test_id( 'GitRepoRepoOkTest' ) )
)
Expand Down
49 changes: 47 additions & 2 deletions main.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ function vipgoci_help_print() :void {
"\t" . '--phpcs-path=FILE Full path to PHPCS script.' . PHP_EOL .
"\t" . '--phpcs-standard=STRING Specify which PHPCS standard(s) to use. Separate by commas.' . PHP_EOL .
"\t" . ' If nothing is specified, the \'WordPress\' standard is used.' . PHP_EOL .
"\t" . '--phpcs-standards-to-ignore PHPCS standards to ignore when searching for PHPCS standards/sniffs' . PHP_EOL .
"\t" . ' available during startup. See details in README.md.' . PHP_EOL .
"\t" . '--phpcs-severity=NUMBER Specify severity for PHPCS.' . PHP_EOL .
"\t" . '--phpcs-sniffs-include=ARRAY Specify which sniffs to include when PHPCS scanning,' . PHP_EOL .
"\t" . ' should be an array with items separated by commas.' . PHP_EOL .
Expand Down Expand Up @@ -283,6 +285,7 @@ function vipgoci_options_recognized() :array {
'phpcs-php-path:',
'phpcs-path:',
'phpcs-standard:',
'phpcs-standards-to-ignore:',
'phpcs-severity:',
'phpcs-sniffs-include:',
'phpcs-sniffs-exclude:',
Expand Down Expand Up @@ -537,7 +540,7 @@ function vipgoci_run_init_options_phpcs( array &$options ) :void {

/*
* Process --phpcs-standard -- expected to be
* a string
* a string.
*/
if ( empty( $options['phpcs-standard'] ) ) {
$options['phpcs-standard'] = array(
Expand All @@ -554,6 +557,42 @@ function vipgoci_run_init_options_phpcs( array &$options ) :void {
);
}

/*
* Process --phpcs-standards-to-ignore -- expected to be
* a string.
*/
if ( empty( $options['phpcs-standards-to-ignore'] ) ) {
$options['phpcs-standards-to-ignore'] = array();
} else {
vipgoci_option_array_handle(
$options,
'phpcs-standards-to-ignore',
array(),
array(),
',',
false
);
}

/*
* Ensure that --phpcs-standard and --phpcs-standards-to-ignore
* do not intersect.
*/
if ( ! empty(
array_intersect(
$options['phpcs-standard'],
$options['phpcs-standards-to-ignore']
)
) ) {
vipgoci_sysexit(
'--phpcs-standard and --phpcs-standards-to-ignore cannot share values',
array(
'phpcs-standard' => $options['phpcs-standard'],
'phpcs-standards-to-ignore' => $options['phpcs-standards-to-ignore'],
)
);
}

/*
* Process --phpcs-sniffs-include and --phpcs-sniffs-exclude
* -- both expected to be an array.
Expand Down Expand Up @@ -2745,10 +2784,16 @@ function vipgoci_run_scan(
* invalid sniffs from the options on the fly and
* post a message to users about the invalid sniffs.
*/

$debug_phpcs_info = array(); // Needed for reference, not used here.

vipgoci_phpcs_validate_sniffs_in_options_and_report(
$options
$options,
$debug_phpcs_info
);

unset( $debug_phpcs_info );

/*
* Set to use new PHPCS standard if needed.
*/
Expand Down
59 changes: 40 additions & 19 deletions phpcs-scan.php
Original file line number Diff line number Diff line change
Expand Up @@ -1325,12 +1325,14 @@ function( $sniff_item ) {
* Do this by getting a list of valid sniffs
* and check if each and every one is in the list.
*
* @param array $options Options needed.
* @param array $options Options needed (reference).
* @param array $debug_phpcs_info Reference to array to save PHPCS debug info.
*
* @return void
*/
function vipgoci_phpcs_validate_sniffs_in_options_and_report(
array &$options
array &$options,
array &$debug_phpcs_info
) :void {
// If PHPCS scanning is disabled, do not do anything.
if ( false === $options['phpcs'] ) {
Expand All @@ -1340,11 +1342,12 @@ function vipgoci_phpcs_validate_sniffs_in_options_and_report(
vipgoci_log(
'Validating sniffs provided in options',
array(
'phpcs-path' => $options['phpcs-path'],
'phpcs-php-path' => $options['phpcs-php-path'],
'phpcs-standard' => $options['phpcs-standard'],
'phpcs-sniffs-exclude' => $options['phpcs-sniffs-exclude'],
'phpcs-sniffs-include' => $options['phpcs-sniffs-include'],
'phpcs-path' => $options['phpcs-path'],
'phpcs-php-path' => $options['phpcs-php-path'],
'phpcs-standard' => $options['phpcs-standard'],
'phpcs-standards-to-ignore' => $options['phpcs-standards-to-ignore'],
'phpcs-sniffs-exclude' => $options['phpcs-sniffs-exclude'],
'phpcs-sniffs-include' => $options['phpcs-sniffs-include'],
)
);

Expand All @@ -1361,15 +1364,26 @@ function vipgoci_phpcs_validate_sniffs_in_options_and_report(
/*
* Get all valid sniffs for all standards.
*/
$all_standards_arr = vipgoci_phpcs_get_all_standards(
$all_standards_arr_unfiltered = vipgoci_phpcs_get_all_standards(
$options['phpcs-path'],
$options['phpcs-php-path']
);

/*
* Filter away PHPCS sniffs configured
* to ignore.
*/
$all_standards_arr_filtered = array_values(
array_diff(
$all_standards_arr_unfiltered,
$options['phpcs-standards-to-ignore']
)
);

$phpcs_sniffs_valid_for_all_standards = vipgoci_phpcs_get_sniffs_for_standard(
$options['phpcs-path'],
$options['phpcs-php-path'],
$all_standards_arr
$all_standards_arr_filtered
);

/*
Expand Down Expand Up @@ -1559,18 +1573,25 @@ function vipgoci_phpcs_validate_sniffs_in_options_and_report(
);
}

// Save debug information, used in logging also.
$debug_phpcs_info = array(
'phpcs-path' => $options['phpcs-path'],
'phpcs-php-path' => $options['phpcs-php-path'],
'phpcs-standard' => $options['phpcs-standard'],
'phpcs-sniffs-include-after' => $options['phpcs-sniffs-include'],
'phpcs-sniffs-include-invalid' => $phpcs_sniffs_include_invalid,
'phpcs-sniffs-exclude-after' => $options['phpcs-sniffs-exclude'],
'phpcs-sniffs-exclude-invalid' => $phpcs_sniffs_exclude_invalid,
'phpcs-sniffs-excluded-and-included' => $phpcs_sniffs_excluded_and_included,
'phpcs-sniffs-valid-for-selected-standards' => $phpcs_sniffs_valid_for_selected_standards,
'phpcs-sniffs-valid-for-all-standards' => $phpcs_sniffs_valid_for_all_standards,
'all-phpcs-standards-unfiltered' => $all_standards_arr_unfiltered,
'all-phpcs-standards-filtered' => $all_standards_arr_filtered,
);

vipgoci_log(
'Validated sniffs provided in options',
array(
'phpcs-path' => $options['phpcs-path'],
'phpcs-php-path' => $options['phpcs-php-path'],
'phpcs-standard' => $options['phpcs-standard'],
'phpcs-sniffs-include-after' => $options['phpcs-sniffs-include'],
'phpcs-sniffs-include-invalid' => $phpcs_sniffs_include_invalid,
'phpcs-sniffs-exclude-after' => $options['phpcs-sniffs-exclude'],
'phpcs-sniffs-exclude-invalid' => $phpcs_sniffs_exclude_invalid,
'phpcs-sniffs-excluded-and-included' => $phpcs_sniffs_excluded_and_included,
)
$debug_phpcs_info
);
}

Expand Down
64 changes: 64 additions & 0 deletions tests/integration/MainRunInitOptionsPhpcsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ final class MainRunInitOptionsPhpcsTest extends TestCase {
* Set up all variables.
*/
protected function setUp() :void {
require_once __DIR__ . '/../unit/helper/IndicateTestId.php';

$this->phpcs_path = vipgoci_unittests_get_config_value(
'phpcs-scan',
'phpcs-path',
Expand Down Expand Up @@ -73,6 +75,7 @@ public function testRunInitOptionsPhpcsDefaults() :void {
'phpcs-skip-scanning-via-labels-allowed' => null,
'phpcs-path' => null,
'phpcs-standard' => null,
'phpcs-standards-to-ignore' => null,
'phpcs-sniffs-include' => null,
'phpcs-sniffs-exclude' => null,
'phpcs-runtime-set' => null,
Expand All @@ -93,6 +96,7 @@ public function testRunInitOptionsPhpcsDefaults() :void {
'phpcs-skip-scanning-via-labels-allowed' => false,
'phpcs-path' => null,
'phpcs-standard' => array( 'WordPress' ),
'phpcs-standards-to-ignore' => array(),
'phpcs-sniffs-include' => array(),
'phpcs-sniffs-exclude' => array(),
'phpcs-runtime-set' => array(),
Expand Down Expand Up @@ -130,6 +134,7 @@ public function testRunInitOptionsPhpcsCustom() :void {
'phpcs-skip-scanning-via-labels-allowed' => 'true',
'phpcs-path' => $this->phpcs_path,
'phpcs-standard' => 'WordPress,myStandard1',
'phpcs-standards-to-ignore' => 'myStandardToIgnore1,myStandardToIgnore2',
'phpcs-sniffs-include' => 'Sniff1,Sniff2',
'phpcs-sniffs-exclude' => 'Sniff3,Sniff4',
'phpcs-runtime-set' => 'key1 value1,key2 value2',
Expand All @@ -148,6 +153,7 @@ public function testRunInitOptionsPhpcsCustom() :void {
'phpcs-skip-scanning-via-labels-allowed' => true,
'phpcs-path' => $this->phpcs_path,
'phpcs-standard' => array( 'WordPress', 'myStandard1' ),
'phpcs-standards-to-ignore' => array( 'myStandardToIgnore1', 'myStandardToIgnore2' ),
'phpcs-sniffs-include' => array( 'Sniff1', 'Sniff2' ),
'phpcs-sniffs-exclude' => array( 'Sniff3', 'Sniff4' ),
'phpcs-runtime-set' => array(
Expand All @@ -162,4 +168,62 @@ public function testRunInitOptionsPhpcsCustom() :void {
$this->options
);
}

/**
* Test function. Check for vipgoci_sysexit() call
* when invalid options are used.
*
* @covers ::vipgoci_run_init_options_phpcs
*/
public function testRunInitOptionsPhpcsInvalid() :void {
$options_test = vipgoci_unittests_options_test(
$this->options,
array(),
$this
);

if ( -1 === $options_test ) {
return;
}

// Set options with invalid values.
$this->options = array(
'phpcs' => 'true',
'phpcs-skip-folders-in-repo-options-file' => 'true',
'phpcs-skip-scanning-via-labels-allowed' => 'true',
'phpcs-path' => $this->phpcs_path,
'phpcs-standard' => 'WordPress,myStandard1',
'phpcs-standards-to-ignore' => 'myStandard1', // Same value as in --phpcs-standard.
'phpcs-sniffs-include' => 'Sniff1,Sniff2',
'phpcs-sniffs-exclude' => 'Sniff3,Sniff4',
'phpcs-runtime-set' => 'key1 value1,key2 value2',
'phpcs-skip-folders' => 'myfolder1,myfolder2',
'phpcs-severity' => 5,
);

vipgoci_unittests_indicate_test_id( 'MainRunInitOptionsPhpcsTest' );

ob_start();

vipgoci_run_init_options_phpcs(
$this->options
);

$printed_data = ob_get_contents();

ob_end_clean();

vipgoci_unittests_remove_indication_for_test_id( 'MainRunInitOptionsPhpcsTest' );

if ( true === vipgoci_unittests_debug_mode_on() ) {
echo $printed_data;
}

$printed_data_found = strpos(
$printed_data,
'--phpcs-standard and --phpcs-standards-to-ignore cannot share values'
);

$this->assertNotFalse( $printed_data_found );
}
}
Loading

0 comments on commit 36cb4d9

Please sign in to comment.