-
-
Notifications
You must be signed in to change notification settings - Fork 241
Enforce PSR-12 and organise imports on Winter CMS core files #1188
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
Draft
bennothommo
wants to merge
44
commits into
develop
Choose a base branch
from
fix/psr-12
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from 1 commit
Commits
Show all changes
44 commits
Select commit
Hold shift + click to select a range
e7ebbb2
Enforce PSR-12 on Winter CMS core files
bennothommo 66bd3f3
Additional code style fixes to improve future diffs and IDE support
bennothommo dbf6019
Use Composer-derived PHPCS, udpate GitHub Actions
bennothommo ce14395
Update GitHub Actions
bennothommo 87171ca
Reset modules before checking code quality
bennothommo e23c0b2
Exclude some rules for partials and views
bennothommo b2ffbe9
Add rule for array indentation
bennothommo 7b72f82
Fix reference to File facade
bennothommo 2643609
Merge branch 'develop' into fix/psr-12
bennothommo 52a824f
Split off Winter CMS code style ruleset to its own XML
bennothommo a6b814b
Remove partial from exclusion list
bennothommo 236c459
Add "winter:sniff" command
bennothommo 47fbf2a
Merge branch 'develop' into fix/psr-12
bennothommo 9d1b92f
Fix remaining code smells
bennothommo b1a5a79
Change alias command
bennothommo 1da2568
Add support for `--fix` option to `sniff` command
LukeTowers 51af67d
Alias `winter:test` to `test`
LukeTowers 0ae77a8
Improve / relocate PHPCS stubs
LukeTowers 1dd04fc
Update composer scripts
LukeTowers f2e7289
Add class constant visibility
LukeTowers 041dbb1
Fix remaining warnings
LukeTowers 61b127f
Add progress flag to phpcs
LukeTowers 33a1518
Add initial version of NoGlobalAliasesSniffTest
LukeTowers afedfb9
Add support for --parallel option to winter:sniff
LukeTowers 69f19e3
Fix remaining global imports
LukeTowers bace8e7
Ignore the project's phpcs.xml file when exporting it as a new project
LukeTowers 16d7cc2
Fix overzealous find/replace
LukeTowers 09b945e
Remove debug code
LukeTowers 02c8469
Use Winter's Url facade instead of Laravel's
LukeTowers 6fe5671
Typo fix
LukeTowers fb92ce3
Allow use statements to reference classes in the same namespace
LukeTowers 27207c2
Fix default scaffolding stub files to conform to coding standard
LukeTowers 1d5e517
Merge branch 'develop' into fix/psr-12
bennothommo a816643
Merge branch 'develop' into fix/psr-12
LukeTowers 1729c6d
Merge branch 'develop' into fix/psr-12
LukeTowers 9775264
Merge branch 'develop' into fix/psr-12
LukeTowers a601865
Update Parameter.php
LukeTowers 847f215
Update PluginManager.php
LukeTowers ee482e6
Update WinterTest.php
LukeTowers f56fb2f
Update EventLog.php
LukeTowers b58f831
Update SecurityPolicyTest.php
LukeTowers e461c12
Merge branch 'develop' into fix/psr-12
LukeTowers 6ab422a
Merge branch 'develop' into fix/psr-12
LukeTowers 7414960
Style fixes
LukeTowers 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
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,279 @@ | ||
| <?php | ||
|
|
||
| namespace System\Console; | ||
|
|
||
| use Illuminate\Support\Facades\File; | ||
| use Symfony\Component\Process\Exception\ProcessSignaledException; | ||
| use Symfony\Component\Process\ExecutableFinder; | ||
| use Symfony\Component\Process\Process; | ||
| use System\Classes\PluginManager; | ||
|
|
||
| /** | ||
| * Console command to check code style and formatting issues. | ||
| * | ||
| * If a plugin is provided, this command will search for a `phpcs.xml file inside the plugin's directory. If not found, | ||
| * the user will be prompted to create one if they wish. | ||
| */ | ||
| class WinterSniff extends BaseScaffoldCommand | ||
| { | ||
| /** | ||
| * @var string|null The default command name for lazy loading. | ||
| */ | ||
| protected static $defaultName = 'winter:sniff'; | ||
|
|
||
| /** | ||
| * @var string The console command name. | ||
| */ | ||
| protected $name = 'winter:sniff'; | ||
|
|
||
| /** | ||
| * The console command description. | ||
| */ | ||
| protected $description = 'Validates source code to ensure a consistent coding style.'; | ||
|
|
||
| /** | ||
| * @var string The console command signature as ignoreValidationErrors causes options not to be registered. | ||
| */ | ||
| protected $signature = 'winter:sniff | ||
| {paths?* : The path to the files and/or directories to check, if you wish to limit the scope of files checked.} | ||
| {?--c|config= : Path to a custom PHPCS configuration XML file} | ||
| {?--p|plugin= : Checks the coding style of a plugin} | ||
| {?--e|no-warnings : Ignore warnings and only show errors} | ||
| {?--s|summary : Display a summary of the results} | ||
| '; | ||
|
|
||
| protected $stubs = [ | ||
| 'scaffold/phpcs/phpcs.xml.stub' => 'phpcs.xml', | ||
| ]; | ||
|
|
||
| /** | ||
| * Create a new command instance. | ||
| */ | ||
| public function __construct() | ||
| { | ||
| parent::__construct(); | ||
|
|
||
| // Register aliases for backwards compatibility with October | ||
| $this->setAliases(['winter:phpcs']); | ||
| } | ||
|
|
||
| /** | ||
| * Execute the console command. | ||
| * | ||
| * @throws \Winter\Storm\Exception\ApplicationException | ||
| * @return int|void | ||
| */ | ||
| public function handle() | ||
| { | ||
| $configFile = $this->getConfigFile(); | ||
|
|
||
| if (!File::exists($configFile)) { | ||
| $this->error(sprintf('No configuration file found. Exiting.', $configFile)); | ||
| return 1; | ||
| } | ||
|
|
||
| $phpCs = $this->findPhpCsExecutable(); | ||
|
|
||
| if (is_null($phpCs)) { | ||
| $this->error('Unable to find the `phpcs` executable. Please ensure that you have installed the developer | ||
| dependencies through Composer.'); | ||
| return 1; | ||
| } | ||
|
|
||
| $phpCsArgs = $this->buildPhpCsArgs($phpCs, $configFile); | ||
|
|
||
| ini_set('memory_limit', '512M'); | ||
| $process = new Process($phpCsArgs, base_path()); | ||
|
|
||
| // Set an unlimited timeout | ||
| $process->setTimeout(0); | ||
|
|
||
| // Attempt to set tty mode, catch and warn with the exception message if unsupported | ||
| try { | ||
| $process->setTty(true); | ||
| } catch (\Throwable $e) { | ||
| $this->warn($e->getMessage()); | ||
| } | ||
|
|
||
| $exitCode = 1; | ||
|
|
||
| try { | ||
| $exitCode = $process->run(function ($type, $line) { | ||
| $this->output->write($line); | ||
| }); | ||
| } catch (ProcessSignaledException $e) { | ||
| if (extension_loaded('pcntl') && $e->getSignal() !== SIGINT) { | ||
| throw $e; | ||
| } | ||
|
|
||
| return 1; | ||
| } | ||
|
|
||
| if ($exitCode === 0) { | ||
| return $this->components->info('No coding style issues found.'); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Gets the config file path. | ||
| * | ||
| * If the config file is not found, the user will be prompted to create one if they wish. | ||
| */ | ||
| protected function getConfigFile(): ?string | ||
| { | ||
| $path = $this->expectedConfigPath(); | ||
|
|
||
| if (!File::exists($path)) { | ||
| $this->warn(sprintf('Configuration file %s not found.', $path)); | ||
|
|
||
| if ($this->confirm('Would you like to create a new configuration file?')) { | ||
| $this->createConfigFile(); | ||
| } | ||
| } | ||
|
|
||
| return $path; | ||
| } | ||
|
|
||
| /** | ||
| * Determines the expected path for the config file. | ||
| * | ||
| * For plugins, this will be a "phpcs.xml" file inside the plugin's directory. For the core, this will be a | ||
| * "phpcs.xml" file in the root directory of the project. | ||
| */ | ||
| protected function expectedConfigPath(): ?string | ||
| { | ||
| if ($this->option('config')) { | ||
| return $this->option('config'); | ||
| } | ||
|
|
||
| if ($this->option('plugin')) { | ||
| $pluginPath = PluginManager::instance()->getPluginPath($this->getPluginIdentifier()); | ||
|
|
||
| if (is_null($pluginPath)) { | ||
| $this->error(sprintf('Plugin %s not found.', $this->getPluginIdentifier())); | ||
| } | ||
|
|
||
| return $pluginPath . '/phpcs.xml'; | ||
| } | ||
|
|
||
| return base_path('phpcs.xml'); | ||
| } | ||
|
|
||
| /** | ||
| * Creates a new configuration file for PHPCS. | ||
| */ | ||
| protected function createConfigFile(): void | ||
| { | ||
| if ($this->option('plugin')) { | ||
| $this->vars = [ | ||
| 'plugin' => $this->getPluginIdentifier(), | ||
| 'plugin_code' => str_replace('.', '_', $this->getPluginIdentifier()), | ||
| ]; | ||
| $this->makeStub('scaffold/phpcs/phpcs.xml.stub'); | ||
| return; | ||
| } | ||
|
|
||
| File::copy( | ||
| __DIR__ . '/scaffold/phpcs/phpcs.core.xml.stub', | ||
| $this->option('config') ?? base_path('phpcs.xml') | ||
| ); | ||
| } | ||
|
|
||
| protected function getDestinationForStub(string $stubName): string | ||
| { | ||
| if ($this->option('config')) { | ||
| return $this->option('config'); | ||
| } | ||
|
|
||
| return parent::getDestinationForStub($stubName); | ||
| } | ||
|
|
||
| public function getPluginIdentifier($identifier = null): string | ||
| { | ||
| $pluginManager = PluginManager::instance(); | ||
| $pluginName = $identifier ?? $this->option('plugin'); | ||
| $pluginName = $pluginManager->normalizeIdentifier($pluginName); | ||
|
|
||
| if (!$pluginManager->hasPlugin($pluginName)) { | ||
| $this->error(sprintf('Plugin %s not found.', $this->getPluginIdentifier())); | ||
| } | ||
|
|
||
| return $pluginName; | ||
| } | ||
|
|
||
| /** | ||
| * Finds the `phpcs` executable in the system. | ||
| * | ||
| * This should be in the `vendor/bin` directory of the project, if the project has developer dependencies installed | ||
| * through Composer. | ||
| */ | ||
| protected function findPhpCsExecutable(): ?string | ||
| { | ||
| return (new ExecutableFinder()) | ||
| ->find( | ||
| 'phpcs', | ||
| base_path('vendor/bin/phpcs'), | ||
| [ | ||
| base_path('vendor'), | ||
| ] | ||
| ); | ||
| } | ||
|
|
||
| /** | ||
| * Gets the base path where files and directories will be checked. | ||
| * | ||
| * If the `--plugin` option is provided, this will return the path to the plugin. Otherwise, it will return the base | ||
| * path of the project. | ||
| * | ||
| * @return string | ||
| */ | ||
| protected function getBasePath(): string | ||
| { | ||
| if ($this->option('plugin')) { | ||
| $pluginPath = PluginManager::instance()->getPluginPath($this->getPluginIdentifier()); | ||
|
|
||
| if (is_null($pluginPath)) { | ||
| $this->error(sprintf('Plugin %s not found.', $this->getPluginIdentifier())); | ||
| } | ||
|
|
||
| return $pluginPath; | ||
| } | ||
|
|
||
| return base_path(); | ||
| } | ||
|
|
||
| /** | ||
| * Builds the arguments to pass to the `phpcs` executable. | ||
| * | ||
| * @return string[] | ||
| */ | ||
| protected function buildPhpCsArgs(string $phpCs, string $configFile): array | ||
| { | ||
| $args = [ | ||
| $phpCs, | ||
| '-d', | ||
| 'memory_limit=512M', | ||
| '--basepath=' . $this->getBasePath(), | ||
| '--standard=' . $configFile, | ||
| ]; | ||
|
|
||
| if ($this->option('no-warnings')) { | ||
| $args[] = '--warning-severity=0'; | ||
| } | ||
|
|
||
| if ($this->option('summary')) { | ||
| $args[] = '--report=summary'; | ||
| } | ||
|
|
||
| $args = array_merge( | ||
| $args, | ||
| $this->argument('paths') ?: ( | ||
| ($this->option('plugin')) | ||
| ? [PluginManager::instance()->getPluginPath($this->getPluginIdentifier())] | ||
| : [] | ||
| ) | ||
| ); | ||
|
|
||
| return $args; | ||
| } | ||
| } | ||
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,24 @@ | ||
| <?xml version="1.0"?> | ||
| <ruleset name="WinterCMSCore"> | ||
| <description>The coding standard for Winter CMS core.</description> | ||
|
|
||
| <!-- Import Winter CMS code style ruleset --> | ||
| <rule ref="./phpcs.base.xml" /> | ||
|
|
||
| <arg name="extensions" value="php" /> | ||
| <arg name="colors" /> | ||
|
|
||
| <file>bootstrap/</file> | ||
| <file>config/</file> | ||
| <file>modules/</file> | ||
| <file>plugins/winter/demo/</file> | ||
|
|
||
| <!-- Ignore vendor files --> | ||
| <exclude-pattern>*/vendor/*</exclude-pattern> | ||
| <!-- Ignore manifest test fixtures --> | ||
| <exclude-pattern>modules/system/tests/fixtures/manifest/*</exclude-pattern> | ||
| <!-- Ignore this view file as fixing the issues in here will break the template --> | ||
| <exclude-pattern>modules/system/views/exception.php</exclude-pattern> | ||
| <!-- Ignore this test case completely as it's testing a parse error --> | ||
| <exclude-pattern>tests/fixtures/plugins/testvendor/goto/Plugin.php</exclude-pattern> | ||
| </ruleset> |
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,10 @@ | ||
| <?xml version="1.0"?> | ||
| <ruleset name="{{ plugin_code }}"> | ||
| <description>Coding style for {{ plugin }}.</description> | ||
|
|
||
| <!-- Import Winter CMS code style ruleset --> | ||
| <rule ref="./phpcs.base.xml" /> | ||
|
|
||
| <arg name="extensions" value="php" /> | ||
| <arg name="colors" /> | ||
| </ruleset> |
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.