Skip to content
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

Extend valid-sprintf ESLint rule to catch placeholders that should be numbered #20574

Merged
merged 54 commits into from
Apr 3, 2020

Conversation

swissspidy
Copy link
Member

Description

This bug fix / enhancement extends the @wordpress/valid-sprintf ESLint rule to detect sprintf usage with multiple unordered placeholders, which is a bad practice.

With this PR, this leads to a better experience for translators and users, as otherwise it might be impossible to translate certain strings correctly.

It does not contain a fixer for it, as it couldn't be reliable—especially when using a mix of unordered and ordered placeholders.

NB: I also updated the code to use ESLint's messageId feature to make the rules & tests easier to read.

Fixes #20554.

Note: This PR builds on top of the changes in #20555, which should preferably be merged first.

How has this been tested?

Extended unit tests and ran the new rules against Gutenberg code base.

Screenshots

Types of changes

Bug fix (non-breaking change which fixes an issue)

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows the accessibility standards.
  • My code has proper inline documentation.
  • I've included developer documentation if appropriate.
  • I've updated all React Native files affected by any refactorings/renamings in this PR.

@swissspidy swissspidy added the [Package] ESLint plugin /packages/eslint-plugin label Mar 2, 2020
@swissspidy swissspidy added the Internationalization (i18n) Issues or PRs related to internationalization efforts label Mar 2, 2020
@github-actions
Copy link

github-actions bot commented Mar 2, 2020

Size Change: +727 B (0%)

Total Size: 885 kB

Filename Size Change
build/block-editor/index.js 102 kB -177 B (0%)
build/block-editor/style-rtl.css 10.6 kB -128 B (1%)
build/block-editor/style.css 10.6 kB -129 B (1%)
build/block-library/index.js 110 kB +1 B
build/blocks/index.js 57.5 kB -1 B
build/components/index.js 195 kB -2 B (0%)
build/edit-post/index.js 92.5 kB +229 B (0%)
build/edit-post/style-rtl.css 12.1 kB +63 B (0%)
build/edit-post/style.css 12.1 kB +64 B (0%)
build/edit-site/index.js 9.78 kB +665 B (6%) 🔍
build/edit-site/style-rtl.css 4.68 kB +70 B (1%)
build/edit-site/style.css 4.68 kB +71 B (1%)
build/element/index.js 4.44 kB +1 B
ℹ️ View Unchanged
Filename Size Change
build/a11y/index.js 1.02 kB 0 B
build/annotations/index.js 3.45 kB 0 B
build/api-fetch/index.js 3.8 kB 0 B
build/autop/index.js 2.59 kB 0 B
build/blob/index.js 620 B 0 B
build/block-directory/index.js 6.03 kB 0 B
build/block-directory/style-rtl.css 760 B 0 B
build/block-directory/style.css 760 B 0 B
build/block-library/editor-rtl.css 7.22 kB 0 B
build/block-library/editor.css 7.22 kB 0 B
build/block-library/style-rtl.css 7.53 kB 0 B
build/block-library/style.css 7.54 kB 0 B
build/block-library/theme-rtl.css 669 B 0 B
build/block-library/theme.css 671 B 0 B
build/block-serialization-default-parser/index.js 1.65 kB 0 B
build/block-serialization-spec-parser/index.js 3.1 kB 0 B
build/components/style-rtl.css 16.6 kB 0 B
build/components/style.css 16.5 kB 0 B
build/compose/index.js 6.21 kB 0 B
build/core-data/index.js 10.7 kB 0 B
build/data-controls/index.js 1.03 kB 0 B
build/data/index.js 8.23 kB 0 B
build/date/index.js 5.37 kB 0 B
build/deprecated/index.js 772 B 0 B
build/dom-ready/index.js 569 B 0 B
build/dom/index.js 3.05 kB 0 B
build/edit-navigation/index.js 2.71 kB 0 B
build/edit-navigation/style-rtl.css 239 B 0 B
build/edit-navigation/style.css 241 B 0 B
build/edit-widgets/index.js 4.43 kB 0 B
build/edit-widgets/style-rtl.css 3.74 kB 0 B
build/edit-widgets/style.css 3.74 kB 0 B
build/editor/editor-styles-rtl.css 423 B 0 B
build/editor/editor-styles.css 426 B 0 B
build/editor/index.js 42.8 kB 0 B
build/editor/style-rtl.css 3.49 kB 0 B
build/editor/style.css 3.49 kB 0 B
build/escape-html/index.js 733 B 0 B
build/format-library/index.js 6.95 kB 0 B
build/format-library/style-rtl.css 502 B 0 B
build/format-library/style.css 502 B 0 B
build/hooks/index.js 1.93 kB 0 B
build/html-entities/index.js 622 B 0 B
build/i18n/index.js 3.57 kB 0 B
build/is-shallow-equal/index.js 710 B 0 B
build/keyboard-shortcuts/index.js 2.3 kB 0 B
build/keycodes/index.js 1.7 kB 0 B
build/list-reusable-blocks/index.js 2.99 kB 0 B
build/list-reusable-blocks/style-rtl.css 226 B 0 B
build/list-reusable-blocks/style.css 226 B 0 B
build/media-utils/index.js 4.84 kB 0 B
build/notices/index.js 1.57 kB 0 B
build/nux/index.js 3.01 kB 0 B
build/nux/style-rtl.css 616 B 0 B
build/nux/style.css 613 B 0 B
build/plugins/index.js 2.54 kB 0 B
build/primitives/index.js 1.5 kB 0 B
build/priority-queue/index.js 780 B 0 B
build/redux-routine/index.js 2.84 kB 0 B
build/rich-text/index.js 14.5 kB 0 B
build/server-side-render/index.js 2.54 kB 0 B
build/shortcode/index.js 1.69 kB 0 B
build/token-list/index.js 1.28 kB 0 B
build/url/index.js 4.01 kB 0 B
build/viewport/index.js 1.6 kB 0 B
build/warning/index.js 1.14 kB 0 B
build/wordcount/index.js 1.17 kB 0 B

compressed-size-action

@gziolo gziolo requested a review from aduth March 2, 2020 11:27
@aduth
Copy link
Member

aduth commented Mar 2, 2020

Nice! I can plan to take a look at this and #20554

You may also be interested in eslint-plugin-wpcalypso, where I'd authored a handful of rules like this and others.

Specifically, there is this rule:

https://github.com/Automattic/wp-calypso/blob/master/packages/eslint-plugin-wpcalypso/docs/rules/i18n-named-placeholders.md

I would be curious to have your opinion: Both this pull request and the above i18n-named-placeholders rule address the same problem, but the latter enforces that these parameters be named, not simply numbered. Do you have any thoughts on whether this should be enforced one way or the other? If I recall correctly, the idea with enforcing named parameters was mostly a point of clarification, where it can be difficult (without associated translator comment) to infer the meaning of a placeholder.

@swissspidy
Copy link
Member Author

@aduth Awesome, thank you!

eslint-plugin-wpcalypso seems to contain some rules that might be valuable to port over to this one. I'll definitely check it out more closely 👍

The issues with named parameters are probably a) that they are misleading (people could mistakenly translate them), and b) that they are not natively supported in PHP. Encouraging named placeholders would diverge the (WordPress) JS and PHP code base in a way that there would be duplicate strings and translators would have to learn two different styles of placeholders.

@aduth
Copy link
Member

aduth commented Mar 2, 2020

The issues with named parameters are [...] that they are not natively supported in PHP.

Huh! For some reason, I thought that they were. I can see how this is an issue.

@swissspidy swissspidy force-pushed the fix/eslint-plugin-valid-sprintf-rule branch from ef6b0a3 to 3ae191b Compare March 11, 2020 16:25
@swissspidy swissspidy changed the base branch from add/i18n-eslint-rules to master April 2, 2020 08:54
packages/eslint-plugin/rules/valid-sprintf.js Outdated Show resolved Hide resolved
Comment on lines 178 to +179
const nextStep = sprintf(
'\nRun %s to build the latest version of %s, then open %s to get started!\n',
'\nRun %1$s to build the latest version of %2$s, then open %3$s to get started!\n',
Copy link
Member

Choose a reason for hiding this comment

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

I don't know that we need to do it within the scope of this pull request, but we should enhance the rule to consider sprintf only from @wordpress/i18n, as a "solution" to allow the original usage here.

packages/eslint-plugin/rules/valid-sprintf.js Outdated Show resolved Hide resolved
@aduth
Copy link
Member

aduth commented Apr 15, 2020

One thing I missed in review here is that because we added a new utils folder, and because most packages define a files field, the utils folder must have been included in this field if it's necessary for runtime use (which it is). This unfortunately caused errors for developers upgrading to the latest version of the package including these changes.

See: #21610

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Internationalization (i18n) Issues or PRs related to internationalization efforts [Package] ESLint plugin /packages/eslint-plugin
Projects
None yet
Development

Successfully merging this pull request may close these issues.

sprintf ESLint rule does not check for numbered placeholders
2 participants