diff --git a/config/commands/lint.yml b/config/commands/lint.yml index 251d160ce..56f30c171 100644 --- a/config/commands/lint.yml +++ b/config/commands/lint.yml @@ -21,3 +21,7 @@ command: extensions: ${toolkit.lint.php.extensions} exclude: ${toolkit.lint.php.exclude} options: ${toolkit.lint.php.options} + lint-css: + options: + config: ${toolkit.lint.css.config} + files: ${toolkit.lint.css.files} diff --git a/config/runner/toolkit-test.yml b/config/runner/toolkit-test.yml index bfd55fea1..3a3493285 100644 --- a/config/runner/toolkit-test.yml +++ b/config/runner/toolkit-test.yml @@ -92,7 +92,7 @@ toolkit: lint: eslint: config: .eslintrc.json - packages: 'eslint-config-drupal eslint-plugin-yml' + packages: 'eslint-config-drupal eslint-plugin-yml stylelint stylelint-config-drupal' ignores: [ '${toolkit.build.dist.root}/*', '.cache/*', 'vendor/*', 'web/*', 'dist/*' ] extensions_yaml: [ '.yml', '.yaml' ] options_yaml: '' @@ -102,6 +102,9 @@ toolkit: extensions: [ 'php', 'module', 'inc', 'theme', 'install' ] exclude: [ '${toolkit.build.dist.root}/', '.cache/', 'vendor/', 'web/' ] options: '' + css: + config: .stylelintrc.json + files: '"${toolkit.build.custom-code-folder}/themes/*/css/*.css" "!${toolkit.build.custom-code-folder}/themes/*/css/*.min.css"' axe-scan: config: axe-scan.config.json urls: diff --git a/src/TaskRunner/Commands/LintCommands.php b/src/TaskRunner/Commands/LintCommands.php index e5b704e6e..67bd9f777 100644 --- a/src/TaskRunner/Commands/LintCommands.php +++ b/src/TaskRunner/Commands/LintCommands.php @@ -27,8 +27,6 @@ public function getConfigurationFile() /** * Setup the ESLint configurations and dependencies. * - * Check configurations at config/default.yml - 'toolkit.lint.eslint'. - * * @command toolkit:setup-eslint * * @option config The eslint config file. @@ -36,14 +34,12 @@ public function getConfigurationFile() * @option drupal-root The drupal root. * @option packages The npm packages to install. * @option force If true, the config file will be deleted. - * - * @return int */ public function toolkitSetupEslint(array $options = [ - 'config' => InputOption::VALUE_OPTIONAL, + 'config' => InputOption::VALUE_REQUIRED, 'ignores' => InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, - 'drupal-root' => InputOption::VALUE_OPTIONAL, - 'packages' => InputOption::VALUE_OPTIONAL, + 'drupal-root' => InputOption::VALUE_REQUIRED, + 'packages' => InputOption::VALUE_REQUIRED, 'force' => false, ]) { @@ -139,8 +135,6 @@ private function generateEslintConfigurations(string $config, array $options) /** * Run lint YAML. * - * Check configurations at config/default.yml - 'toolkit.lint.eslint'. - * * @command toolkit:lint-yaml * * @option config The eslint config file. @@ -165,8 +159,6 @@ public function toolkitLintYaml(array $options = [ /** * Run lint JS. * - * Check configurations at config/default.yml - 'toolkit.lint.eslint'. - * * @command toolkit:lint-js * * @option config The eslint config file. @@ -225,8 +217,6 @@ private function toolkitRunEsLint(string $config, array $extensions, string $opt /** * Run lint PHP. * - * Check configurations at config/default.yml - 'toolkit.lint.php'. - * * @command toolkit:lint-php * * @option exclude The eslint config file. @@ -266,4 +256,43 @@ public function toolkitLintPhp(array $options = [ return $result->getExitCode(); } + /** + * Run lint CSS. + * + * @command toolkit:lint-css + * + * @option exclude The stylelint config file. + * @option files The files to check. + * + * @aliases tk-css + */ + public function toolkitLintCss(array $options = [ + 'config' => InputOption::VALUE_REQUIRED, + 'files' => InputOption::VALUE_REQUIRED, + ]) + { + $tasks = []; + + // Make sure eslint is properly installed. + $tasks[] = $this->taskExec($this->getBin('run'))->arg('toolkit:setup-eslint'); + + // Make sure the stylelint-config-drupal and stylelint are installed. + $tasks[] = $this->taskExecStack() + ->exec('npm -v || npm i npm') + ->exec('[ -f package.json ] || npm init -y --scope') + ->exec('npm list stylelint-config-drupal && npm update stylelint-config-drupal || npm install stylelint-config-drupal -y'); + + // Generate the config file if missing. + if (!file_exists($options['config'])) { + $data = ['extends' => 'stylelint-config-drupal']; + $tasks[] = $this->taskWriteToFile($options['config']) + ->text(json_encode($data, JSON_PRETTY_PRINT)); + } + + $tasks[] = $this->taskExec($this->getNodeBinPath('stylelint')) + ->rawArg($options['files']); + + return $this->collectionBuilder()->addTaskList($tasks); + } + } diff --git a/tests/fixtures/commands/lint.yml b/tests/fixtures/commands/lint.yml index 8944e32ea..1c7fde4b0 100644 --- a/tests/fixtures/commands/lint.yml +++ b/tests/fixtures/commands/lint.yml @@ -5,8 +5,8 @@ - contains: | [Simulator] Simulating Exec('npm ini -y') [Simulator] Running npm ini -y - [Simulator] Simulating Exec('npm install --save-dev eslint-config-drupal eslint-plugin-yml -y') - [Simulator] Running npm install --save-dev eslint-config-drupal eslint-plugin-yml -y + [Simulator] Simulating Exec('npm install --save-dev eslint-config-drupal eslint-plu ... nt-config-drupal -y') + [Simulator] Running npm install --save-dev eslint-config-drupal eslint-plugin-yml stylelint stylelint-config-drupal -y [File\Write] Writing to .eslintrc.json. [Simulator] Simulating File\Write('.prettierignore') ->text('*.yml') @@ -34,8 +34,8 @@ [Simulator] Running rm .eslintrc.json [Simulator] Simulating Exec('npm ini -y') [Simulator] Running npm ini -y - [Simulator] Simulating Exec('npm install --save-dev eslint-config-drupal eslint-plugin-yml -y') - [Simulator] Running npm install --save-dev eslint-config-drupal eslint-plugin-yml -y + [Simulator] Simulating Exec('npm install --save-dev eslint-config-drupal eslint-plu ... nt-config-drupal -y') + [Simulator] Running npm install --save-dev eslint-config-drupal eslint-plugin-yml stylelint stylelint-config-drupal -y [Simulator] Simulating File\Write('.prettierignore') ->text('*.yml')