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

Lint: Add rule to prohibit @wordpress/* unstable and experimental features #47712

Merged
merged 19 commits into from
Nov 27, 2020

Conversation

sirreal
Copy link
Member

@sirreal sirreal commented Nov 24, 2020

Changes proposed in this Pull Request

Introduce a new lint rule. It bans __experimental- and __unstable-prefixed imported names from @wordpress/* packages.

Experimental features caused problem recently (p58i-9K9-p2).

  • __unstable cannot be configured
  • __experimental can be configured by providing a configuration object: { "@wordpress/foo": [ "__experimentalBar" ] } allows the __experimentalBar import from @wordpress/foo package, e.g. import { __experimentalBar } from '@wordpress/foo';.

Adds this to the default wpcalypso rule set. Disable the rule for the only experimental feature we have e2e tests for.

Of course, the rule can always be disabled at the eslint level case-by-case.

Results
  ✘  https://google.com/#q=wpcalypso%2Fwp-no-unsafe-features

     Usage of `__experimentalInserterMenuExtension` from `@wordpress/block-editor` is not allowed


     apps/editing-toolkit/editing-toolkit-plugin/block-inserter-modifications/contextual-tips.js:10:10
      8 |  */
      9 | import { useState } from '@wordpress/element';
   > 10 | import { __experimentalInserterMenuExtension as InserterMenuExtension } from '@wordpress/block-editor';
        |          ^
     11 | import { registerPlugin } from '@wordpress/plugins';
     12 |
     13 | /**

  ✘  https://google.com/#q=wpcalypso%2Fwp-no-unsafe-features

     Usage of `__experimentalGetSettings` from `@wordpress/date` is not allowed


     apps/editing-toolkit/editing-toolkit-plugin/event-countdown-block/blocks/src/edit.js:8:20
      6 |  * WordPress dependencies
      7 |  */
   >  8 | import { dateI18n, __experimentalGetSettings } from '@wordpress/date';
        |                    ^
      9 | import { __ } from '@wordpress/i18n';
     10 | import { Button, DateTimePicker, Dropdown, Placeholder } from '@wordpress/components';
     11 |

  ✘  https://google.com/#q=wpcalypso%2Fwp-no-unsafe-features

     Usage of `__experimentalGetSettings` from `@wordpress/date` is not allowed


     apps/editing-toolkit/editing-toolkit-plugin/newspack-blocks/synced-newspack-blocks/blocks/carousel/edit.js:13:20
     11 |  */
     12 | import { __ } from '@wordpress/i18n';
   > 13 | import { dateI18n, __experimentalGetSettings } from '@wordpress/date';
        |                    ^
     14 | import { Component, createRef, Fragment } from '@wordpress/element';
     15 | import { InspectorControls } from '@wordpress/editor';
     16 | import {

  ✘  https://google.com/#q=wpcalypso%2Fwp-no-unsafe-features

     Usage of `__experimentalGetSettings` from `@wordpress/date` is not allowed


     apps/editing-toolkit/editing-toolkit-plugin/newspack-blocks/synced-newspack-blocks/blocks/homepage-articles/edit.js:25:20
     23 |  */
     24 | import { __ } from '@wordpress/i18n';
   > 25 | import { dateI18n, __experimentalGetSettings } from '@wordpress/date';
        |                    ^
     26 | import { Component, Fragment, RawHTML } from '@wordpress/element';
     27 | import {
     28 |       BlockControls,

  ✘  https://google.com/#q=wpcalypso%2Fwp-no-unsafe-features

     Usage of `__experimentalBlock` from `@wordpress/block-editor` is not allowed


     apps/editing-toolkit/editing-toolkit-plugin/premium-content/blocks/buttons/edit.js:5:23
     3 |  */
     4 | // eslint-disable-next-line wpcalypso/import-docblock
   > 5 | import { InnerBlocks, __experimentalBlock as Block } from '@wordpress/block-editor';
       |                       ^
     6 | import { compose } from '@wordpress/compose';
     7 | import { withDispatch, withSelect } from '@wordpress/data';
     8 | import { useEffect } from '@wordpress/element';

  ✘  https://google.com/#q=wpcalypso%2Fwp-no-unsafe-features

     Usage of `__experimentalBlock` from `@wordpress/block-editor` is not allowed


     apps/editing-toolkit/editing-toolkit-plugin/premium-content/blocks/login-button/edit.js:12:39
     10 | import { useCallback } from '@wordpress/element';
     11 | import { PanelBody, RangeControl } from '@wordpress/components';
   > 12 | import { InspectorControls, RichText, __experimentalBlock as Block } from '@wordpress/block-editor';
        |                                       ^
     13 |
     14 | /**
     15 |  * Internal dependencies

  ✘  https://google.com/#q=wpcalypso%2Fwp-no-unsafe-features

     Usage of `__experimentalBlock` from `@wordpress/block-editor` is not allowed


     apps/editing-toolkit/editing-toolkit-plugin/premium-content/index.js:11:10
      9 | import apiFetch from '@wordpress/api-fetch';
     10 | import { getBlockType, registerBlockType, unregisterBlockType } from '@wordpress/blocks';
   > 11 | import { __experimentalBlock } from '@wordpress/block-editor';
        |          ^
     12 |
     13 | /**
     14 |  * Internal dependencies

  ✘  https://google.com/#q=wpcalypso%2Fwp-no-unsafe-features

     Usage of `__experimentalMainDashboardButton` from `@wordpress/interface` is not allowed


     apps/wpcom-block-editor/src/calypso/features/iframe-bridge-server.js:13:10
     11 | import { addQueryArgs, getQueryArg } from '@wordpress/url';
     12 | import { registerPlugin } from '@wordpress/plugins';
   > 13 | import { __experimentalMainDashboardButton as MainDashboardButton } from '@wordpress/interface';
        |          ^
     14 | import { Button } from '@wordpress/components';
     15 | import { wordpress } from '@wordpress/icons';
     16 | import { Component, useEffect, useState } from 'react';

  ✘  https://google.com/#q=wpcalypso%2Fwp-no-unsafe-features

     Usage of `__experimentalInserterMenuExtension` from `@wordpress/block-editor` is not allowed


     apps/wpcom-block-editor/src/wpcom/features/tracking/wpcom-inserter-menu-search-term.js:11:10
      9 | import { useState } from '@wordpress/element';
     10 | import { useSelect } from '@wordpress/data';
   > 11 | import { __experimentalInserterMenuExtension as InserterMenuExtension } from '@wordpress/block-editor';
        |          ^
     12 |
     13 | /**
     14 |  * Internal dependencies

✘ 9 problems (9 errors, 0 warnings)

Testing instructions

  • Just the editing toolkit: npx eslint-nibble --rule wpcalypso/wp-no-unsafe-features apps/editing-toolkit
  • Most everything (slow!): npx eslint-nibble --rule wpcalypso/wp-no-unsafe-features apps client packages

Closes #47551

@matticbot
Copy link
Contributor

@matticbot
Copy link
Contributor

This PR does not affect the size of JS and CSS bundles shipped to the user's browser.

Generated by performance advisor bot at iscalypsofastyet.com.

@sirreal sirreal added the [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. label Nov 25, 2020
@sirreal sirreal marked this pull request as ready for review November 25, 2020 13:50
@sirreal sirreal self-assigned this Nov 25, 2020
@sirreal sirreal requested review from a team November 25, 2020 13:51
@@ -26,5 +26,8 @@
},
"devDependencies": {
"babel-eslint": "^10.1.0"
},
"scripts": {
"test": "jest"
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't this be tested as part of yarn test-packages in the root? Why do we need our own jest call?

Copy link
Member Author

Choose a reason for hiding this comment

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

I moved into the package and did yarn test. I expected that to work and was surprised when it didn't. With this change it does work, but if that's in violation of the repo setup I'm happy to drop the change.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think having a test command here may be a bit confusing:

  • Technically we don't run this command on CI, so it can break at anytime and go unnoticed. In CI we only do yarn test-packages in the root.
  • With the current setup, the way to run tests for a single package is yarn test-packages packages/eslint-plugin-wpcalypso. Doing cd packages/eslint-plugin-wpcalypso && yarn jest also works, but that's a trick

@scinos
Copy link
Contributor

scinos commented Nov 25, 2020

I changed the 'Code style' build to lint all files and not only the files changed in this PR. This should show existing violations of this rule (if any)

@scinos
Copy link
Contributor

scinos commented Nov 25, 2020

Existing violations in the codebase

image

I think we should "fix" them before merging this new rule. And by "fix" I mean either remove the usage, or if too hard/expensive add an explicit //eslint-disable-next-line for that specific import.

@sirreal sirreal added the [Status] Needs e2e Testing Gutenberg Edge Run e2e tests with a special site that is running the latest Gutenberg plugin snapshot label Nov 25, 2020
@sirreal
Copy link
Member Author

sirreal commented Nov 25, 2020

Thanks for the review @scinos 👍

I think we should "fix" them before merging this new rule.

Fixing these is on the short list, especially considering they caused a production issue recently.

Teams use these features because they needed them and the features are fine as long as the Gutenberg version we're using doesn't change. We have control over the Gutenberg version, so what we want to do is make sure we have tests on the features so they don't break without notice. For most (all?) of the features, we can probably add a test and configure the rule:

// Experimental Gutenberg features that we depend on in Calypso (and other projects)
// Tests will fail if an experimental feature is no longer being exported from one
// of the @wordpress/* packages. The purpose of these tests is to give us an early
// warning if an experimental feature has been removed or renamed.
const EXPERIMENTAL_FEATURES = {
'@wordpress/block-editor': [
// Used in the premium content block in the Editing Toolkit plugin
'__experimentalBlock',
],
};

https://github.com/Automattic/wp-calypso/blob/b311e2bb1f08bf82fe36f145ac9272863b4bc14e/.eslintrc.js#L392-L395

I'll see what that looks like, if it's really that simple we can do it here. Otherwise I'd prefer to get the responsible teams to handle each case.

'wpcalypso/jsx-gridicon-size': 'error',
'wpcalypso/jsx-classname-namespace': 'error',
'wpcalypso/redux-no-bound-selectors': 'error',
'wpcalypso/wp-no-unsafe-features': 'error',
Copy link
Member Author

Choose a reason for hiding this comment

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

This line adds the new rule. The rest just rewrite from confusing numbers to clear strings.

@fullofcaffeine
Copy link
Contributor

fullofcaffeine commented Nov 25, 2020

Great work here 💯!

I've tried it out today and have a few questions:

1) Running npx eslint-nibble --rule wpcalypso/wp-no-unsafe-features apps client packages locally didn't yield any lint errors for me:

~/workspace/code/wp-calypso (add/eslint-experimental-features●)$ npx eslint-nibble --rule wpcalypso/wp-no-unsafe-features apps client packages                                                          [system] 
Invalid import, only literal imports are supported. File /home/fullofcaffeine/workspace/code/wp-calypso/client/components/localized-moment/provider.js:35                                                                                                     
Invalid import, only literal imports are supported. File /home/fullofcaffeine/workspace/code/wp-calypso/client/lib/flags/index.js:9                                                                                                                           
Invalid import, only literal imports are supported. File /home/fullofcaffeine/workspace/code/wp-calypso/client/signup/config/step-components.js:78                                                                                                            
Invalid import, only literal imports are supported. File /home/fullofcaffeine/workspace/code/wp-calypso/packages/calypso-codemods/api.js:13                                                                                                                   
Invalid import, only literal imports are supported. File /home/fullofcaffeine/workspace/code/wp-calypso/packages/effective-module-tree/index.js:68                                                                                                            
Invalid import, only literal imports are supported. File /home/fullofcaffeine/workspace/code/wp-calypso/packages/effective-module-tree/index.js:114

No lint failures found for rule(s): wpcalypso/wp-no-unsafe-features
Try running again without "--rule"

Am I missing something?

2) Should we also detect when unstable members are used, like this?

@sirreal sirreal force-pushed the add/eslint-experimental-features branch from e90d65b to e97061e Compare November 26, 2020 11:51
@sirreal
Copy link
Member Author

sirreal commented Nov 26, 2020

Proposing for Gutenberg: WordPress/gutenberg#27301

@sirreal sirreal force-pushed the add/eslint-experimental-features branch from e97061e to 1cab570 Compare November 26, 2020 15:33
@@ -23,10 +23,21 @@ const gutenbergUser =
// of the @wordpress/* packages. The purpose of these tests is to give us an early
// warning if an experimental feature has been removed or renamed.
const EXPERIMENTAL_FEATURES = {
Copy link
Member Author

@sirreal sirreal Nov 26, 2020

Choose a reason for hiding this comment

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

It's unclear whether and when this is actually run. I can see the spec file in CircleCI logs, but I don't see the describe actually appear like it isn't being run. We may need to tag this describe somehow, e.g. @parallel and/or whatever tag runs on Gutenberg edge tests.

@fullofcaffeine can own that bit? I'd expect this to run as part of the full suite and the Gutenberg edge suites. We can handle that in a separate PR (which could include the changes to this file).

Copy link
Contributor

Choose a reason for hiding this comment

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

@fullofcaffeine can own that bit?

Sure! Tracked it here. Will get to it as soon as I can.

Examples of **incorrect** code for this rule:

```js
/* eslint-disable wpcalypso/no-unsafe-wp-apis */
Copy link
Member Author

Choose a reason for hiding this comment

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

This seems like encouraging folks to disable the rule right in the docs. That seems like the wrong message. Can we ignore the lint error or add an .eslintrc override?

@@ -7,7 +7,7 @@ Three dots for indicating an ellipsis should be replaced with the UTF-8 characte
The following patterns are considered warnings:

```js
translate( 'Loading' );
translate( 'Loading...' );
Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for fixing this :)

@scinos scinos self-requested a review November 27, 2020 12:39
@sirreal
Copy link
Member Author

sirreal commented Nov 27, 2020

The Gutenberg edge failures are expected and the woo test failure is happening on all PRs.

I'll merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Status] Needs e2e Testing Gutenberg Edge Run e2e tests with a special site that is running the latest Gutenberg plugin snapshot
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Lint: Add eslint rule prohibiting experimental feature usage
4 participants