Problem/Motivation

Since Symfony's YAML parser has some issues https://github.com/symfony/symfony/issues/16234 that allow for invalid yaml to be parsed and in an attempt to assuage some fears in #1920902: Add a Drupal Yaml wrapper so we can default to PECL Yaml component if it is available.

We should add a YAML linting pass to core and contrib so we can ensure YAML is able to be parsed correctly in all our implementations and is able to be parsed by external tools.

Steps to reproduce

Proposed resolution

Add eslint-plugin-yml to our precommit script to ensure YAML is always well formed.

Running core/scripts/dev/commit-code-check.sh from the top level of the checkout will check any changed YAML files.

Running yarn lint:yaml from the core directory will check all YAML files in core.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

How to test the new eslint for yaml files

From the core directory do:
node ./node_modules/eslint/bin/eslint.js --ext .yml .
or run
yarn lint:yaml

Issue fork drupal-2591827

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

neclimdul created an issue. See original summary.

stevector’s picture

elachlan’s picture

elachlan’s picture

Issue summary: View changes
elachlan’s picture

Title: Add a yaml lint step » DrupalCI should return failed for poor code style - yaml
elachlan’s picture

elachlan’s picture

Priority: Normal » Major
elachlan’s picture

elachlan’s picture

Issue summary: View changes
elachlan’s picture

Title: DrupalCI should return failed for poor code style - yaml » DrupalCI should return failed for poor code style - YAML

I suggest yamlJS because it doesn't have a dependency on grunt, like grunt-yamllint does.

elachlan’s picture

sorry, double post.

elachlan’s picture

YesCT’s picture

Issue tags: +Coding standards
Mile23’s picture

Addressing blockers for this issue: #2654650: [meta] Jobs for linting and coding standards

Mile23’s picture

The symfony issue linked above seems to have been fixed with deprecation for symfony 2.8: https://github.com/symfony/symfony/pull/16285

Drupal 8's symfony dependency is 2.7.*, so this is an argument in favor of bumping up to 2.8.* #2611816: Update to symfony 2.8

We should still do YAML linting/CS here, though.

Mixologic’s picture

Component: Code » Jobs and Job Handling
elachlan’s picture

Assigned: neclimdul » Unassigned

@Mixologic - This is the final code style check I believe.

elachlan’s picture

Title: DrupalCI should return failed for poor code style - YAML » DrupalCI should report code style issues - YAML
Category: Task » Feature request

Adjust title.

Mixologic’s picture

Status: Active » Postponed

We can't really do much here until core has decided what the standard is and what tools we should use to enforce that standard. Our maybe wet know that already?

andypost’s picture

PECL extension yml sometimes wrong as well

andypost’s picture

elachlan’s picture

Do we already test if the YAML is parsable?

quietone’s picture

The symfony issue quoted in the IS has been fixed.

catch’s picture

Title: DrupalCI should report code style issues - YAML » Add YAML linting to core coding standards checks
Project: DrupalCI: Test Runner » Drupal core
Version: » 9.2.x-dev
Component: Jobs and Job Handling » other
Category: Feature request » Task
Status: Postponed » Active

This can be added directly in core now without requiring changes to DrupalCI.

Wim Leers’s picture

#24: What changed?

neclimdul’s picture

Curious as well. Happy to make a patch but not sure what needs to be done to make it happen.

catch’s picture

Sorry that would have been useful information to add - since #3178845: Run same checks as committers do on DrupalCI.

longwave’s picture

Status: Active » Needs review
FileSize
15.71 KB

Quick stab at this using https://www.npmjs.com/package/yaml-lint

PHP CodeSniffer claims to check YAML files but it doesn't seem to do a very good job, maybe we should remove it from the equation if we have something better now.

neclimdul’s picture

Status: Needs review » Reviewed & tested by the community

Did a quick check and edited a file to reproduce the common problem we where running into and it caught it so this works for me.

PHPCS: core/tests/Drupal/Tests/Core/Asset/library_test_files/css_bad_category.libraries.yml passed
✖ YAML Lint failed for /.../core/tests/Drupal/Tests/Core/Asset/library_test_files/css_bad_category.libraries.yml
✖ duplicated mapping key at line 4, column -92:
      css:

Specifically this would cause the problem where Symfony would use the later value for the key and Pecl would use the first and we'd end up with brokenness. I expect the core team or maybe tests have been really great at catching these because I haven't seen them in a while but this looks like a great lint for catching errors with yaml.

Going to RTBC because the approach makes sense to me and correctly linted problems.

catch’s picture

This looks good.

It won't help with issues like #3112452: Fix indentation consistency in core's yaml files. though where the YAML is valid but confusing - so I think we should open a follow-up to see if we can add formatting checks as well as the raw linting.

longwave’s picture

I wonder if it's worth exploring eslint-plugin-yml as an alternative as that seems to be able to handle coding style as well. We already use a number of eslint plugins.

https://www.npmjs.com/package/eslint-plugin-yml

catch’s picture

Status: Reviewed & tested by the community » Needs review

Back to NR for that. If we can combine linting and coding style in eslint that'd be worth doing I think.

longwave’s picture

This looks like it might be a winner. Running eslint-plugin-yml with the strictest set of options across core reports many errors, mostly because we do not use consistent quoting. But we can switch all the rules off (including Prettier, which implements some YAML rules) and start with the "recommended" set, and get 9 errors:

core/core.services.yml
  1237:5  error  Empty mapping values are forbidden  yml/no-empty-mapping-value
  1241:5  error  Empty mapping values are forbidden  yml/no-empty-mapping-value

core/drupalci.yml
   6:5  error  Empty mapping values are forbidden  yml/no-empty-mapping-value
  48:7  error  Empty mapping values are forbidden  yml/no-empty-mapping-value

core/modules/system/config/install/system.authorize.yml
  1:1  error  Empty mapping values are forbidden  yml/no-empty-mapping-value

core/modules/system/tests/fixtures/HtaccessTest/access_test.yml
  1:1  error  Empty documents are forbidden  yml/no-empty-document

core/modules/system/tests/themes/test_theme_libraries_empty/test_theme_libraries_empty.info.yml
  6:1  error  Empty mapping values are forbidden  yml/no-empty-mapping-value

core/tests/Drupal/Tests/Core/Asset/library_test_files/empty.libraries.yml
  1:1  error  Empty documents are forbidden  yml/no-empty-document

core/tests/Drupal/Tests/Core/Asset/library_test_files/invalid_file.libraries.yml
  1:0  error  Parsing error: All collection items must start at the same column

As an example the two errors in core.services.yml are where we have a "tags" key but nothing inside it:

  ajax_response.attachments_processor:
    class: Drupal\Core\Ajax\AjaxResponseAttachmentsProcessor
    tags:
    arguments: ['@asset.resolver', '@config.factory', '@asset.css.collection_renderer', '@asset.js.collection_renderer', '@request_stack', '@renderer', '@module_handler']
  html_response.attachments_processor:
    class: Drupal\Core\Render\HtmlResponseAttachmentsProcessor
    tags:
    arguments: ['@asset.resolver', '@config.factory', '@asset.css.collection_renderer', '@asset.js.collection_renderer', '@request_stack', '@renderer', '@module_handler']

eslint-plugin-yml also only brings with it a single child dependency as we already have the rest of ESLint installed.

longwave’s picture

The attached patch builds on #33:

  • The errors in core.services.yml are fixed
  • The four deliberately malformed test fixtures are ignored
  • drupalci.yml has the yml/no-empty-mapping-value ignored for the time being

This only leaves system.authorize.yml, which as far as I can see is no longer used in core, apart from a migration that writes to it? Probably worth ignoring this here and exploring in a followup issue?

longwave’s picture

Added a patch in #2715145: Remove system.authorize config to deal with system.authorize.yml.

neclimdul’s picture

Status: Needs review » Needs work

So figured I'd put this through the paces locally and see what happened. Everything is pretty straight forward and seemed to work but I was a little bit interested in how node ./node_modules/eslint/bin/eslint.js "$TOP_LEVEL/$FILE" would behave outside the core directory. So I modified sites/development.services.yml and got this weird error.

Checking sites/development.services.yml

PHPCS: sites/development.services.yml passed

Oops! Something went wrong! :(

ESLint: 7.11.0

ESLint couldn't find the plugin "eslint-plugin-prettier".

(The package "eslint-plugin-prettier" was not found when loaded as a Node module from the directory "/home/X/Projects/d9_2".)

It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:

    npm install eslint-plugin-prettier@latest --save-dev

The plugin "eslint-plugin-prettier" was referenced from the config file in "../.eslintrc.json » ./core/.eslintrc.json".

If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team.

Not sure how its connected or why it would only seem to affect files outside of core. Especially since eslint-plugin-prettier is clearly installed but thought I'd provide the feedback.

Also... it passed even though the file was not valid so marking NW. Passing may actually just be a weird byproduct of the error and how node chose to return from the error though.

longwave’s picture

Status: Needs work » Needs review
FileSize
6.46 KB
6.46 KB

Addressed #36 with an additional option when running eslint. Also added --quiet to match the other calls to eslint in commit-code-check.sh.

neclimdul’s picture

Status: Needs review » Reviewed & tested by the community
FileSize
654 bytes

Everything looks great! The real interdiff attached :-D So easy to mess that up when you're making a quick change.

Side note: I accidentally had a big folder of config data sitting in the directory when I ran it this time and it did expose something interesting. With a lot of yaml changes this _really_ slows down the script. Maybe not a deal breaker but wanted to share.

longwave’s picture

Whoops, thanks for fixing that. Another reason I should embrace the Gitlab workflow for all issues!

longwave’s picture

I also think we should drop YAML linting from PHPCS if we have a better tool doing it, PHPCS isn't doing a very good job anyway - let's open a followup for that if this is committed.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
/Users/alex/dev/drupal/core/modules/system/config/install/system.authorize.yml
  1:1  error  Empty mapping values are forbidden  yml/no-empty-mapping-value

/Users/alex/dev/drupal/core/modules/user/config/install/user.mail.yml
  2:8  error  Parsing error: Multi-line double-quoted string needs to be sufficiently indented

We have a couple of new (i guess) errors to fix.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

longwave’s picture

While working on this I found a major bug in the recent change to user.mail.yml: #3212034: Account emails are missing newlines due to malformed YAML

longwave’s picture

Status: Needs work » Needs review
FileSize
7.45 KB

user.mail.yml was fixed in the linked issue.

system.authorize.yml will be deleted in #2715145: Remove system.authorize config but we can fix the syntax here temporarily.

Rerolled #37 and fixed the above.

longwave’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll

Needs rerolling.

longwave’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll

Rerolled as a merge request.

daffie’s picture

Could we update the IS with:

  1. the chosen solution and why
  2. how to run the added testing

I think we also should add a CR for the added test functionality.

longwave’s picture

Issue summary: View changes
Issue tags: -Needs issue summary update

Updated IS.

longwave’s picture

quietone’s picture

The doc page should be updated as well, I think. https://www.drupal.org/docs/develop/development-tools/running-core-devel...

When I read the CR, which is fine, I thought it would be helpful to link to the doc page, so I added it. Took it straight from https://www.drupal.org/node/3185278.

daffie’s picture

Issue summary: View changes

Updated the IS with how to run eslint for yaml files.

daffie’s picture

Status: Needs review » Needs work

I found out that after installing the MR and running the command from the IS that the changes for core/core.services.yml are needed to pass the new eslint for yaml files.

I think we need a followup for when there is a change to core/package.json that all files are tested to see if they pass. Just like we did for PHPCS in #3224583: The testbot does not run PHPCS on all files when core/phpcs.xml.dist is changed.

Changing the status to needs work for the unresolved threads.

daffie’s picture

Issue summary: View changes
longwave’s picture

Status: Needs work » Needs review

Upgraded eslint-plugin-yml, responded to the other comments.

daffie’s picture

Status: Needs review » Needs work

Just one open unresolved thread.

longwave’s picture

Status: Needs work » Needs review

Need to check here that drupalci actually runs as expected - the default validate_codebase steps should be skipped and nightwatchjs should run as normal.

longwave’s picture

The validate_codebase step is missing entirely from the Jenkins output (as it does nothing, this is fine) and the Nightwatch tests ran as expected so to me this is an OK change to make. We probably should follow our own best practices and validate all our YAML except when we are explicitly testing invalid YAML.

daffie’s picture

Status: Needs review » Reviewed & tested by the community

The new yarn package for eslint-plugin-yml has been added in the MR.
The file core/scripts/dev/commit-code-check.sh has been updated for the package.
When I run the command to test for failures with the new plugin, I get a number of vialures which are fixed in the MR (core/drupalci.yml and core/core.services.yml).
The IS is in order and there is an CR.
After the MR has landed the page https://www.drupal.org/drupalorg/docs/drupal-ci/customizing-drupalci-tes... needs updating.
For me it is RTBC.

  • catch committed b85fb24 on 9.3.x
    Issue #2591827 by longwave, neclimdul, elachlan, daffie: Add YAML...
catch’s picture

Status: Reviewed & tested by the community » Fixed

Committed b85fb24 and pushed to 9.3.x. Thanks!

Wim Leers’s picture

Published change record. Noticed this in an unexpectedly broken contrib build…

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.