diff --git a/packages/a11y/src/index.js b/packages/a11y/src/index.js index 7129b2957e20c..e082e15ca6fb7 100644 --- a/packages/a11y/src/index.js +++ b/packages/a11y/src/index.js @@ -1,6 +1,13 @@ +/** + * WordPress dependencies + */ +import domReady from '@wordpress/dom-ready'; + +/** + * Internal dependencies + */ import addContainer from './addContainer'; import clear from './clear'; -import domReady from '@wordpress/dom-ready'; import filterMessage from './filterMessage'; /** diff --git a/packages/a11y/src/test/addContainer.test.js b/packages/a11y/src/test/addContainer.test.js index 7b09cc630ba6d..e6c722078f74f 100644 --- a/packages/a11y/src/test/addContainer.test.js +++ b/packages/a11y/src/test/addContainer.test.js @@ -1,3 +1,6 @@ +/** + * Internal dependencies + */ import addContainer from '../addContainer'; describe( 'addContainer', () => { diff --git a/packages/a11y/src/test/clear.test.js b/packages/a11y/src/test/clear.test.js index c139f0d664ab5..02438dda1a4ec 100644 --- a/packages/a11y/src/test/clear.test.js +++ b/packages/a11y/src/test/clear.test.js @@ -1,3 +1,6 @@ +/** + * Internal dependencies + */ import clear from '../clear'; describe( 'clear', () => { diff --git a/packages/a11y/src/test/filterMessage.test.js b/packages/a11y/src/test/filterMessage.test.js index 3dcdf54e9b18d..95302abb8d1ce 100644 --- a/packages/a11y/src/test/filterMessage.test.js +++ b/packages/a11y/src/test/filterMessage.test.js @@ -1,3 +1,6 @@ +/** + * Internal dependencies + */ import filterMessage from '../filterMessage'; describe( 'filterMessage', () => { diff --git a/packages/a11y/src/test/index.test.js b/packages/a11y/src/test/index.test.js index 3737e4e444754..08c9489bed2ae 100644 --- a/packages/a11y/src/test/index.test.js +++ b/packages/a11y/src/test/index.test.js @@ -1,4 +1,14 @@ +/** + * WordPress dependencies + */ +import domReady from '@wordpress/dom-ready'; + +/** + * Internal dependencies + */ import { setup, speak } from '../'; +import clear from '../clear'; +import filterMessage from '../filterMessage'; jest.mock( '../clear', () => { return jest.fn(); @@ -14,10 +24,6 @@ jest.mock( '../filterMessage', () => { } ); } ); -import clear from '../clear'; -import domReady from '@wordpress/dom-ready'; -import filterMessage from '../filterMessage'; - describe( 'speak', () => { let containerPolite = document.getElementById( 'a11y-speak-polite' ); let containerAssertive = document.getElementById( 'a11y-speak-assertive' ); diff --git a/packages/blob/src/test/index.js b/packages/blob/src/test/index.js index 49adedc33e58c..7604e3956b6d2 100644 --- a/packages/blob/src/test/index.js +++ b/packages/blob/src/test/index.js @@ -1,3 +1,6 @@ +/** + * Internal dependencies + */ import { isBlobURL, } from '../'; diff --git a/packages/block-library/src/image/edit.native.js b/packages/block-library/src/image/edit.native.js index 822723ce141f6..1035a6391ce11 100644 --- a/packages/block-library/src/image/edit.native.js +++ b/packages/block-library/src/image/edit.native.js @@ -18,17 +18,21 @@ import { } from 'lodash'; /** - * Internal dependencies + * WordPress dependencies */ import { MediaPlaceholder, RichText, BlockControls, InspectorControls, BottomSheet } from '@wordpress/editor'; import { Toolbar, ToolbarButton, Spinner, Dashicon } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; -import ImageSize from './image-size'; import { isURL } from '@wordpress/url'; -import styles from './styles.scss'; import { compose } from '@wordpress/compose'; import { withSelect } from '@wordpress/data'; +/** + * Internal dependencies + */ +import ImageSize from './image-size'; +import styles from './styles.scss'; + const MEDIA_UPLOAD_STATE_UPLOADING = 1; const MEDIA_UPLOAD_STATE_SUCCEEDED = 2; const MEDIA_UPLOAD_STATE_FAILED = 3; diff --git a/packages/block-library/src/image/image-size.native.js b/packages/block-library/src/image/image-size.native.js index 8b29b9607e81e..a337a5d14548c 100644 --- a/packages/block-library/src/image/image-size.native.js +++ b/packages/block-library/src/image/image-size.native.js @@ -4,8 +4,8 @@ import { Component } from '@wordpress/element'; /** -* External dependencies -*/ + * External dependencies + */ import { View, Image } from 'react-native'; /** diff --git a/packages/block-library/src/nextpage/index.js b/packages/block-library/src/nextpage/index.js index 7386aceea805b..8ee142f82934f 100644 --- a/packages/block-library/src/nextpage/index.js +++ b/packages/block-library/src/nextpage/index.js @@ -5,6 +5,10 @@ import { __ } from '@wordpress/i18n'; import { RawHTML } from '@wordpress/element'; import { createBlock } from '@wordpress/blocks'; import { G, Path, SVG } from '@wordpress/components'; + +/** + * Internal dependencies + */ import edit from './edit'; export const name = 'core/nextpage'; diff --git a/packages/block-library/src/paragraph/edit.native.js b/packages/block-library/src/paragraph/edit.native.js index 85183973dddea..3ed4225f7b26d 100644 --- a/packages/block-library/src/paragraph/edit.native.js +++ b/packages/block-library/src/paragraph/edit.native.js @@ -12,7 +12,7 @@ import { parse, createBlock } from '@wordpress/blocks'; import { RichText } from '@wordpress/editor'; /** - * Import style + * Internal dependencies */ import styles from './style.scss'; diff --git a/packages/block-library/src/preformatted/index.js b/packages/block-library/src/preformatted/index.js index 6170275f629d9..f0ee53a942221 100644 --- a/packages/block-library/src/preformatted/index.js +++ b/packages/block-library/src/preformatted/index.js @@ -1,5 +1,5 @@ /** - * WordPress + * WordPress dependencies */ import { __ } from '@wordpress/i18n'; import { createBlock, getPhrasingContentSchema } from '@wordpress/blocks'; diff --git a/packages/block-library/src/pullquote/index.js b/packages/block-library/src/pullquote/index.js index 1dc6126394678..3bbcec5b88d86 100644 --- a/packages/block-library/src/pullquote/index.js +++ b/packages/block-library/src/pullquote/index.js @@ -18,6 +18,9 @@ import { } from '@wordpress/data'; import { Path, Polygon, SVG } from '@wordpress/components'; +/** + * Internal dependencies + */ import { default as edit, SOLID_COLOR_STYLE_NAME, diff --git a/packages/block-library/src/spacer/index.js b/packages/block-library/src/spacer/index.js index 12f362b40f623..d671a24b994c0 100644 --- a/packages/block-library/src/spacer/index.js +++ b/packages/block-library/src/spacer/index.js @@ -4,7 +4,7 @@ import classnames from 'classnames'; /** - * WordPress + * WordPress dependencies */ import { Fragment } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; diff --git a/packages/block-library/src/verse/index.js b/packages/block-library/src/verse/index.js index 0993bfa4f9c7e..17306b3284f00 100644 --- a/packages/block-library/src/verse/index.js +++ b/packages/block-library/src/verse/index.js @@ -1,5 +1,5 @@ /** - * WordPress + * WordPress dependencies */ import { __ } from '@wordpress/i18n'; import { Fragment } from '@wordpress/element'; diff --git a/packages/block-serialization-default-parser/test/index.js b/packages/block-serialization-default-parser/test/index.js index a8749c1c0f262..a3c67e280ef94 100644 --- a/packages/block-serialization-default-parser/test/index.js +++ b/packages/block-serialization-default-parser/test/index.js @@ -4,9 +4,13 @@ import path from 'path'; /** - * Internal dependencies + * WordPress dependencies */ import { jsTester, phpTester } from '@wordpress/block-serialization-spec-parser'; + +/** + * Internal dependencies + */ import { parse } from '../'; describe( 'block-serialization-default-parser-js', jsTester( parse ) ); diff --git a/packages/blocks/src/api/raw-handling/utils.js b/packages/blocks/src/api/raw-handling/utils.js index d917b681f9456..90e6f463ad465 100644 --- a/packages/blocks/src/api/raw-handling/utils.js +++ b/packages/blocks/src/api/raw-handling/utils.js @@ -7,11 +7,11 @@ import { mapValues, mergeWith, includes, noop } from 'lodash'; * WordPress dependencies */ import { unwrap, insertAfter, remove } from '@wordpress/dom'; -import { hasBlockSupport } from '..'; /** * Internal dependencies */ +import { hasBlockSupport } from '..'; import { isPhrasingContent } from './phrasing-content'; /** diff --git a/packages/blocks/src/index.js b/packages/blocks/src/index.js index bb7cde035780f..579665d14b853 100644 --- a/packages/blocks/src/index.js +++ b/packages/blocks/src/index.js @@ -7,6 +7,11 @@ // // Blocks are inferred from the HTML source of a post through a parsing mechanism // and then stored as objects in state, from which it is then rendered for editing. + +/** + * Internal dependencies + */ import './store'; + export * from './api'; export { withBlockContentContext } from './block-content-provider'; diff --git a/packages/components/src/checkbox-control/index.js b/packages/components/src/checkbox-control/index.js index 04d584cdff6e1..d84be2d56e24c 100644 --- a/packages/components/src/checkbox-control/index.js +++ b/packages/components/src/checkbox-control/index.js @@ -1,5 +1,5 @@ /** - * External dependencies + * WordPress dependencies */ import { withInstanceId } from '@wordpress/compose'; diff --git a/packages/components/src/color-palette/index.js b/packages/components/src/color-palette/index.js index c70db00206f49..99f76c99d64cf 100644 --- a/packages/components/src/color-palette/index.js +++ b/packages/components/src/color-palette/index.js @@ -8,7 +8,6 @@ import { map } from 'lodash'; * WordPress dependencies */ import { __, sprintf } from '@wordpress/i18n'; -import Dashicon from '../dashicon'; /** * Internal dependencies @@ -17,6 +16,7 @@ import Button from '../button'; import Dropdown from '../dropdown'; import Tooltip from '../tooltip'; import ColorPicker from '../color-picker'; +import Dashicon from '../dashicon'; export default function ColorPalette( { colors, disableCustomColors = false, value, onChange, className } ) { function applyOrUnset( color ) { diff --git a/packages/components/src/form-token-field/test/lib/token-field-wrapper.js b/packages/components/src/form-token-field/test/lib/token-field-wrapper.js index ff7bc86eb162f..15729d4404041 100644 --- a/packages/components/src/form-token-field/test/lib/token-field-wrapper.js +++ b/packages/components/src/form-token-field/test/lib/token-field-wrapper.js @@ -1,8 +1,12 @@ +/** + * External dependencies + */ +import { unescape } from 'lodash'; + /** * WordPress dependencies */ import { Component } from '@wordpress/element'; -import { unescape } from 'lodash'; /** * Internal dependencies diff --git a/packages/components/src/icon/index.js b/packages/components/src/icon/index.js index fbb2c1bc49df7..f106f7c561511 100644 --- a/packages/components/src/icon/index.js +++ b/packages/components/src/icon/index.js @@ -2,6 +2,10 @@ * WordPress dependencies */ import { cloneElement, createElement, Component, isValidElement } from '@wordpress/element'; + +/** + * Internal dependencies + */ import { Dashicon, SVG } from '../'; function Icon( { icon = null, size, className } ) { diff --git a/packages/components/src/icon/test/index.js b/packages/components/src/icon/test/index.js index a7fea71cb9fac..ec632ef74677b 100644 --- a/packages/components/src/icon/test/index.js +++ b/packages/components/src/icon/test/index.js @@ -7,12 +7,12 @@ import { shallow } from 'enzyme'; * WordPress dependencies */ import { Component } from '@wordpress/element'; -import { Path, SVG } from '../../'; /** * Internal dependencies */ import Icon from '../'; +import { Path, SVG } from '../../'; describe( 'Icon', () => { const className = 'example-class'; diff --git a/packages/components/src/isolated-event-container/index.js b/packages/components/src/isolated-event-container/index.js index 10f26bceb89ed..282e6dc5c5b7a 100644 --- a/packages/components/src/isolated-event-container/index.js +++ b/packages/components/src/isolated-event-container/index.js @@ -1,5 +1,5 @@ /** - * External dependencies + * WordPress dependencies */ import { Component } from '@wordpress/element'; diff --git a/packages/components/src/popover/index.js b/packages/components/src/popover/index.js index 052e53189ba84..47212a3e12f9c 100644 --- a/packages/components/src/popover/index.js +++ b/packages/components/src/popover/index.js @@ -2,7 +2,6 @@ * External dependencies */ import classnames from 'classnames'; -import isShallowEqual from '@wordpress/is-shallow-equal'; /** * WordPress dependencies @@ -10,6 +9,7 @@ import isShallowEqual from '@wordpress/is-shallow-equal'; import { Component, createRef } from '@wordpress/element'; import { focus } from '@wordpress/dom'; import { ESCAPE } from '@wordpress/keycodes'; +import isShallowEqual from '@wordpress/is-shallow-equal'; /** * Internal dependencies diff --git a/packages/components/src/primitives/svg/index.js b/packages/components/src/primitives/svg/index.js index 8b54a777f053b..abb15e121dc2b 100644 --- a/packages/components/src/primitives/svg/index.js +++ b/packages/components/src/primitives/svg/index.js @@ -1,5 +1,5 @@ /** - * External dependencies + * WordPress dependencies */ import { createElement } from '@wordpress/element'; diff --git a/packages/components/src/server-side-render/test/index.js b/packages/components/src/server-side-render/test/index.js index b276987fcafec..c09814771f7a7 100644 --- a/packages/components/src/server-side-render/test/index.js +++ b/packages/components/src/server-side-render/test/index.js @@ -1,3 +1,6 @@ +/** + * Internal dependencies + */ import { rendererPath } from '../index'; describe( 'rendererPath', function() { diff --git a/packages/components/src/spinner/index.native.js b/packages/components/src/spinner/index.native.js index 305019bc8b40d..0c7e9902ffe39 100644 --- a/packages/components/src/spinner/index.native.js +++ b/packages/components/src/spinner/index.native.js @@ -1,3 +1,6 @@ +/** + * External dependencies + */ import { View } from 'react-native'; export default function Spinner( props ) { diff --git a/packages/components/src/toolbar/toolbar-container.native.js b/packages/components/src/toolbar/toolbar-container.native.js index d147c547add6d..887991d2ea123 100644 --- a/packages/components/src/toolbar/toolbar-container.native.js +++ b/packages/components/src/toolbar/toolbar-container.native.js @@ -3,6 +3,9 @@ */ import { View } from 'react-native'; +/** + * Internal dependencies + */ import styles from './style.scss'; const ToolbarContainer = ( props ) => ( diff --git a/packages/compose/src/with-global-events/test/index.js b/packages/compose/src/with-global-events/test/index.js index 31c89bffd77be..4001f219ad594 100644 --- a/packages/compose/src/with-global-events/test/index.js +++ b/packages/compose/src/with-global-events/test/index.js @@ -4,7 +4,7 @@ import TestRenderer from 'react-test-renderer'; /** - * External dependencies + * WordPress dependencies */ import { Component } from '@wordpress/element'; diff --git a/packages/data/src/default-registry.js b/packages/data/src/default-registry.js index f593e59530c31..eabb5ba272f37 100644 --- a/packages/data/src/default-registry.js +++ b/packages/data/src/default-registry.js @@ -1,3 +1,6 @@ +/** + * Internal dependencies + */ import { createRegistry } from './registry'; export default createRegistry(); diff --git a/packages/dom-ready/src/test/index.test.js b/packages/dom-ready/src/test/index.test.js index 63a0d6f4b3ae4..36a5bbbc64056 100644 --- a/packages/dom-ready/src/test/index.test.js +++ b/packages/dom-ready/src/test/index.test.js @@ -1,3 +1,6 @@ +/** + * Internal dependencies + */ import domReady from '../'; describe( 'domReady', () => { diff --git a/packages/e2e-test-utils/src/create-url.js b/packages/e2e-test-utils/src/create-url.js index ff7271c8ebf8f..14437e0476666 100644 --- a/packages/e2e-test-utils/src/create-url.js +++ b/packages/e2e-test-utils/src/create-url.js @@ -4,6 +4,9 @@ import { join } from 'path'; import { URL } from 'url'; +/** + * Internal dependencies + */ import { WP_BASE_URL } from './shared/config'; /** diff --git a/packages/e2e-tests/specs/publish-button.test.js b/packages/e2e-tests/specs/publish-button.test.js index da5cf1d616124..ecdd6bf76b000 100644 --- a/packages/e2e-tests/specs/publish-button.test.js +++ b/packages/e2e-tests/specs/publish-button.test.js @@ -1,3 +1,6 @@ +/** + * WordPress dependencies + */ import { arePrePublishChecksEnabled, disablePrePublishChecks, diff --git a/packages/e2e-tests/specs/publish-panel.test.js b/packages/e2e-tests/specs/publish-panel.test.js index 026c3d8ee35fd..c28a3837d7443 100644 --- a/packages/e2e-tests/specs/publish-panel.test.js +++ b/packages/e2e-tests/specs/publish-panel.test.js @@ -1,3 +1,6 @@ +/** + * WordPress dependencies + */ import { arePrePublishChecksEnabled, disablePrePublishChecks, diff --git a/packages/editor/src/components/block-mover/drag-handle.js b/packages/editor/src/components/block-mover/drag-handle.js index 560a0f50bc078..005487e11c5c7 100644 --- a/packages/editor/src/components/block-mover/drag-handle.js +++ b/packages/editor/src/components/block-mover/drag-handle.js @@ -4,7 +4,7 @@ import classnames from 'classnames'; /** - * WordPress dependencies + * Internal dependencies */ import BlockDraggable from '../block-draggable'; diff --git a/packages/editor/src/components/default-block-appender/index.native.js b/packages/editor/src/components/default-block-appender/index.native.js index 436ecc5772b00..22563f75a086f 100644 --- a/packages/editor/src/components/default-block-appender/index.native.js +++ b/packages/editor/src/components/default-block-appender/index.native.js @@ -11,6 +11,9 @@ import { compose } from '@wordpress/compose'; import { decodeEntities } from '@wordpress/html-entities'; import { withSelect, withDispatch } from '@wordpress/data'; +/** + * Internal dependencies + */ import styles from './style.scss'; export function DefaultBlockAppender( { diff --git a/packages/editor/src/components/media-placeholder/index.native.js b/packages/editor/src/components/media-placeholder/index.native.js index 0b70472c2407f..0c2a234ad9798 100644 --- a/packages/editor/src/components/media-placeholder/index.native.js +++ b/packages/editor/src/components/media-placeholder/index.native.js @@ -3,10 +3,16 @@ */ import { View, Text, Button } from 'react-native'; -import styles from './styles.scss'; - +/** + * WordPress dependencies + */ import { __ } from '@wordpress/i18n'; +/** + * Internal dependencies + */ +import styles from './styles.scss'; + function MediaPlaceholder( props ) { return ( diff --git a/packages/editor/src/components/mobile/bottom-sheet/button.native.js b/packages/editor/src/components/mobile/bottom-sheet/button.native.js index 439e056b93187..c8011f80511f8 100644 --- a/packages/editor/src/components/mobile/bottom-sheet/button.native.js +++ b/packages/editor/src/components/mobile/bottom-sheet/button.native.js @@ -1,6 +1,6 @@ /** -* External dependencies -*/ + * External dependencies + */ import { TouchableOpacity, View, Text } from 'react-native'; /** diff --git a/packages/editor/src/components/mobile/bottom-sheet/cell.native.js b/packages/editor/src/components/mobile/bottom-sheet/cell.native.js index 89970e69b4598..6e01487d388f6 100644 --- a/packages/editor/src/components/mobile/bottom-sheet/cell.native.js +++ b/packages/editor/src/components/mobile/bottom-sheet/cell.native.js @@ -1,6 +1,6 @@ /** -* External dependencies -*/ + * External dependencies + */ import { TouchableOpacity, Text, View, TextInput } from 'react-native'; /** diff --git a/packages/editor/src/components/post-publish-panel/maybe-tags-panel.js b/packages/editor/src/components/post-publish-panel/maybe-tags-panel.js index f2f53c78c26cb..69d600fcae9e4 100644 --- a/packages/editor/src/components/post-publish-panel/maybe-tags-panel.js +++ b/packages/editor/src/components/post-publish-panel/maybe-tags-panel.js @@ -12,6 +12,9 @@ import { compose, ifCondition } from '@wordpress/compose'; import { withSelect } from '@wordpress/data'; import { PanelBody } from '@wordpress/components'; +/** + * Internal dependencies + */ import FlatTermSelector from '../post-taxonomies/flat-term-selector'; const TagsPanel = () => { diff --git a/packages/editor/src/editor-styles/index.js b/packages/editor/src/editor-styles/index.js index c5de582ce074c..5d98c856ed116 100644 --- a/packages/editor/src/editor-styles/index.js +++ b/packages/editor/src/editor-styles/index.js @@ -9,7 +9,7 @@ import { map } from 'lodash'; import { compose } from '@wordpress/compose'; /** - * External dependencies + * Internal dependencies */ import traverse from './traverse'; import urlRewrite from './transforms/url-rewrite'; diff --git a/packages/editor/src/editor-styles/traverse.js b/packages/editor/src/editor-styles/traverse.js index 43b18251bd7df..6a0cc298697ee 100644 --- a/packages/editor/src/editor-styles/traverse.js +++ b/packages/editor/src/editor-styles/traverse.js @@ -1,9 +1,13 @@ /** * External dependencies */ -import { parse, stringify } from './ast'; import traverse from 'traverse'; +/** + * Internal dependencies + */ +import { parse, stringify } from './ast'; + function traverseCSS( css, callback ) { try { const parsed = parse( css ); diff --git a/packages/editor/src/hooks/test/generated-class-name.js b/packages/editor/src/hooks/test/generated-class-name.js index 509b06e61d06b..397ec9ab333ce 100644 --- a/packages/editor/src/hooks/test/generated-class-name.js +++ b/packages/editor/src/hooks/test/generated-class-name.js @@ -4,7 +4,7 @@ import { noop } from 'lodash'; /** - * External dependencies + * WordPress dependencies */ import { applyFilters } from '@wordpress/hooks'; diff --git a/packages/element/src/raw-html.js b/packages/element/src/raw-html.js index 8a604e54e900c..d985c9376d4a2 100644 --- a/packages/element/src/raw-html.js +++ b/packages/element/src/raw-html.js @@ -1,5 +1,5 @@ /** - * External dependencies + * Internal dependencies */ import { createElement } from './react'; diff --git a/packages/eslint-plugin/CHANGELOG.md b/packages/eslint-plugin/CHANGELOG.md index 775abcac66305..9562f47730d07 100644 --- a/packages/eslint-plugin/CHANGELOG.md +++ b/packages/eslint-plugin/CHANGELOG.md @@ -7,6 +7,7 @@ ### New Features - New Rule: [`@wordpress/no-unused-vars-before-return`](https://github.com/WordPress/gutenberg/blob/master/packages/eslint-plugin/docs/rules/no-unused-vars-before-return.md) +- New Rule: [`@wordpress/dependency-group`](https://github.com/WordPress/gutenberg/blob/master/packages/eslint-plugin/docs/rules/dependency-group.md) ## 1.0.0 (2018-12-12) diff --git a/packages/eslint-plugin/README.md b/packages/eslint-plugin/README.md index 1f001411b7319..5e21e8fc99463 100644 --- a/packages/eslint-plugin/README.md +++ b/packages/eslint-plugin/README.md @@ -49,7 +49,8 @@ The granular rulesets will not define any environment globals. As such, if they Rule|Description ---|--- -[no-unused-vars-before-return](docs/rules/no-unused-vars-before-return.md)|Disallow assigning variable values if unused before a return +[no-unused-vars-before-return](/packages/eslint-plugin/docs/rules/no-unused-vars-before-return.md)|Disallow assigning variable values if unused before a return +[dependency-group](/packages/eslint-plugin/docs/rules/dependency-group.md)|Enforce dependencies docblocks formatting ### Legacy diff --git a/packages/eslint-plugin/configs/custom.js b/packages/eslint-plugin/configs/custom.js index 5691c3c5d0c2b..9eb42283099b0 100644 --- a/packages/eslint-plugin/configs/custom.js +++ b/packages/eslint-plugin/configs/custom.js @@ -3,6 +3,7 @@ module.exports = { '@wordpress', ], rules: { + '@wordpress/dependency-group': 'error', '@wordpress/no-unused-vars-before-return': 'error', 'no-restricted-syntax': [ 'error', diff --git a/packages/eslint-plugin/docs/rules/dependency-group.md b/packages/eslint-plugin/docs/rules/dependency-group.md new file mode 100644 index 0000000000000..02c1c4ccb95fe --- /dev/null +++ b/packages/eslint-plugin/docs/rules/dependency-group.md @@ -0,0 +1,36 @@ +# Enforce dependencies docblocks formatting (dependency-group) + +Ensures that all top-level package imports adhere to the dependencies grouping conventions as outlined in the [Coding Guidelines](https://github.com/WordPress/gutenberg/blob/master/docs/contributors/coding-guidelines.md#imports). + +Specifically, this ensures that: + +- An import is preceded by "External dependencies", "WordPress dependencies", or "Internal dependencies" as appropriate by the import source. + +## Rule details + +Examples of **incorrect** code for this rule: + +```js +import { get } from 'lodash'; +import { Component } from '@wordpress/element'; +import edit from './edit'; +``` + +Examples of **correct** code for this rule: + +```js +/* + * External dependencies + */ +import { get } from 'lodash'; + +/* + * WordPress dependencies + */ +import { Component } from '@wordpress/element'; + +/* + * Internal dependencies + */ +import edit from './edit'; +``` diff --git a/packages/eslint-plugin/docs/rules/no-unused-vars-before-return.md b/packages/eslint-plugin/docs/rules/no-unused-vars-before-return.md index 7dba90d405973..357d0d948ff16 100644 --- a/packages/eslint-plugin/docs/rules/no-unused-vars-before-return.md +++ b/packages/eslint-plugin/docs/rules/no-unused-vars-before-return.md @@ -4,7 +4,7 @@ To avoid wastefully computing the result of a function call when assigning a var ## Rule details -The following patterns are considered warnings: +Examples of **incorrect** code for this rule: ```js function example( number ) { @@ -17,7 +17,7 @@ function example( number ) { } ``` -The following patterns are not considered warnings: +Examples of **correct** code for this rule: ```js function example( number ) { diff --git a/packages/eslint-plugin/rules/__tests__/dependencies-docblocks.js b/packages/eslint-plugin/rules/__tests__/dependencies-docblocks.js new file mode 100644 index 0000000000000..74e41626bfcd8 --- /dev/null +++ b/packages/eslint-plugin/rules/__tests__/dependencies-docblocks.js @@ -0,0 +1,67 @@ +/** + * External dependencies + */ +import { RuleTester } from 'eslint'; + +/** + * Internal dependencies + */ +import rule from '../dependency-group'; + +const ruleTester = new RuleTester( { + parserOptions: { + sourceType: 'module', + ecmaVersion: 6, + }, +} ); + +ruleTester.run( 'dependency-group', rule, { + valid: [ + { + code: ` +/* + * External dependencies + */ +import { get } from 'lodash'; +import classnames from 'classnames'; + +/* + * WordPress dependencies + */ +import { Component } from '@wordpress/element'; + +/* + * Internal dependencies + */ +import edit from './edit';`, + }, + ], + invalid: [ + { + code: ` +import { get } from 'lodash'; +import classnames from 'classnames'; +import { Component } from '@wordpress/element'; +import edit from './edit';`, + errors: [ + { message: 'Expected preceding "External dependencies" comment block' }, + { message: 'Expected preceding "WordPress dependencies" comment block' }, + { message: 'Expected preceding "Internal dependencies" comment block' }, + ], + output: ` +/** + * External dependencies + */ +import { get } from 'lodash'; +import classnames from 'classnames'; +/** + * WordPress dependencies + */ +import { Component } from '@wordpress/element'; +/** + * Internal dependencies + */ +import edit from './edit';`, + }, + ], +} ); diff --git a/packages/eslint-plugin/rules/dependency-group.js b/packages/eslint-plugin/rules/dependency-group.js new file mode 100644 index 0000000000000..c92345a905cb7 --- /dev/null +++ b/packages/eslint-plugin/rules/dependency-group.js @@ -0,0 +1,159 @@ +module.exports = { + meta: { + type: 'layout', + docs: { + description: 'Enforce dependencies docblocks formatting', + url: 'https://github.com/WordPress/gutenberg/blob/master/packages/eslint-plugin/docs/rules/dependency-group.md', + }, + schema: [], + fixable: true, + }, + create( context ) { + const comments = context.getSourceCode().getAllComments(); + + /** + * Locality classification of an import, one of "External", + * "WordPress", "Internal". + * + * @typedef {string} WPPackageLocality + */ + + /** + * Given an import source string, returns the locality classification + * of the import sort. + * + * @param {string} source Import source string. + * + * @return {WPPackageLocality} Package locality. + */ + function getPackageLocality( source ) { + if ( source.startsWith( '.' ) ) { + return 'Internal'; + } else if ( source.startsWith( '@wordpress/' ) ) { + return 'WordPress'; + } + + return 'External'; + } + + /** + * Returns true if the given comment node satisfies a desired locality, + * or false otherwise. + * + * @param {espree.Node} node Comment node to check. + * @param {WPPackageLocality} locality Desired package locality. + * + * @return {boolean} Whether comment node satisfies locality. + */ + function isLocalityDependencyBlock( node, locality ) { + const { type, value } = node; + if ( type !== 'Block' ) { + return false; + } + + // (Temporary) Tolerances: + // - Normalize `/**` and `/*` + // - Case insensitive "Dependencies" vs. "dependencies" + // - Ending period + // - "Node" dependencies as an alias for External + + if ( locality === 'External' ) { + locality = '(External|Node)'; + } + + const pattern = new RegExp( `^\\*?\\n \\* ${ locality } [dD]ependencies\\.?\\n $` ); + return pattern.test( value ); + } + + /** + * Returns true if the given node occurs prior in code to a reference, + * or false otherwise. + * + * @param {espree.Node} node Node to test being before reference. + * @param {espree.Node} reference Node against which to compare. + * + * @return {boolean} Whether node occurs before reference. + */ + function isBefore( node, reference ) { + return node.start < reference.start; + } + + /** + * Returns true if a given node is preceded by a comment block + * satisfying a locality requirement, or false otherwise. + * + * @param {espree.Node} node Node to test. + * @param {WPPackageLocality} locality Desired package locality. + * + * @return {boolean} Whether node preceded by locality comment block. + */ + function isPrecededByDependencyBlock( node, locality ) { + return comments.some( ( comment ) => { + return isLocalityDependencyBlock( comment, locality ) && isBefore( comment, node ); + } ); + } + + return { + Program( node ) { + /** + * The set of package localities which have been reported for + * the current program. Each locality is reported at most one + * time, since otherwise the fixer would insert a comment + * block for each individual import statement. + * + * @type {Set} + */ + const reported = new Set(); + + // Since we only care to enforce imports which occur at the + // top-level scope, match on Program and test its children, + // rather than matching the import nodes directly. + node.body.forEach( ( child ) => { + let source; + switch ( child.type ) { + case 'ImportDeclaration': + source = child.source.value; + break; + + case 'CallExpression': + const { callee, arguments: args } = child; + if ( + callee.name === 'require' && + args.length === 1 && + args[ 0 ].type === 'Literal' && + typeof args[ 0 ].value === 'string' + ) { + source = args[ 0 ].value; + } + break; + } + + if ( ! source ) { + return; + } + + const locality = getPackageLocality( source ); + if ( + reported.has( locality ) || + isPrecededByDependencyBlock( child, locality ) + ) { + return; + } + + reported.add( locality ); + + context.report( { + node: child, + message: `Expected preceding "${ locality } dependencies" comment block`, + fix( fixer ) { + return fixer.insertTextBefore( + child, + `/**\n * ${ locality } dependencies\n */\n` + ); + }, + } ); + } ); + }, + }; + }, +}; diff --git a/packages/hooks/src/createAddHook.js b/packages/hooks/src/createAddHook.js index 81b576d9d14e3..79b3d6f0b91d3 100644 --- a/packages/hooks/src/createAddHook.js +++ b/packages/hooks/src/createAddHook.js @@ -1,3 +1,6 @@ +/** + * Internal dependencies + */ import validateNamespace from './validateNamespace.js'; import validateHookName from './validateHookName.js'; import { doAction } from './'; diff --git a/packages/hooks/src/createDidHook.js b/packages/hooks/src/createDidHook.js index 4aac41d4033c0..b5cf3cf687195 100644 --- a/packages/hooks/src/createDidHook.js +++ b/packages/hooks/src/createDidHook.js @@ -1,3 +1,6 @@ +/** + * Internal dependencies + */ import validateHookName from './validateHookName.js'; /** diff --git a/packages/hooks/src/createHooks.js b/packages/hooks/src/createHooks.js index 9915a1167e31f..d61effc36a4ac 100644 --- a/packages/hooks/src/createHooks.js +++ b/packages/hooks/src/createHooks.js @@ -1,3 +1,6 @@ +/** + * Internal dependencies + */ import createAddHook from './createAddHook'; import createRemoveHook from './createRemoveHook'; import createHasHook from './createHasHook'; diff --git a/packages/hooks/src/createRemoveHook.js b/packages/hooks/src/createRemoveHook.js index d9a99468f7a5f..bbca6a6188e56 100644 --- a/packages/hooks/src/createRemoveHook.js +++ b/packages/hooks/src/createRemoveHook.js @@ -1,3 +1,6 @@ +/** + * Internal dependencies + */ import validateNamespace from './validateNamespace.js'; import validateHookName from './validateHookName.js'; import { doAction } from './'; diff --git a/packages/hooks/src/index.js b/packages/hooks/src/index.js index 508e27fc0c140..78a68df809086 100644 --- a/packages/hooks/src/index.js +++ b/packages/hooks/src/index.js @@ -1,3 +1,6 @@ +/** + * Internal dependencies + */ import createHooks from './createHooks'; const { diff --git a/packages/redux-routine/src/is-action.js b/packages/redux-routine/src/is-action.js index 383e2c55f74e2..152119d001fe2 100644 --- a/packages/redux-routine/src/is-action.js +++ b/packages/redux-routine/src/is-action.js @@ -1,5 +1,5 @@ /** - * External imports + * External dependencies */ import { isPlainObject, isString } from 'lodash'; diff --git a/packages/rich-text/src/index.js b/packages/rich-text/src/index.js index 86f7cd1b29ae1..7ce8ed970e6eb 100644 --- a/packages/rich-text/src/index.js +++ b/packages/rich-text/src/index.js @@ -1,3 +1,6 @@ +/** + * Internal dependencies + */ import './store'; export { applyFormat } from './apply-format'; diff --git a/packages/rich-text/src/is-empty.js b/packages/rich-text/src/is-empty.js index f7078eb3440aa..aa7bad7407615 100644 --- a/packages/rich-text/src/is-empty.js +++ b/packages/rich-text/src/is-empty.js @@ -1,3 +1,6 @@ +/** + * Internal dependencies + */ import { LINE_SEPARATOR } from './special-characters'; /** diff --git a/packages/rich-text/src/to-html-string.js b/packages/rich-text/src/to-html-string.js index 7b6d2edfac2c3..324dd2d65d287 100644 --- a/packages/rich-text/src/to-html-string.js +++ b/packages/rich-text/src/to-html-string.js @@ -1,5 +1,5 @@ /** - * Internal dependencies + * WordPress dependencies */ import { diff --git a/packages/scripts/utils/test/index.js b/packages/scripts/utils/test/index.js index 47e1598667a7d..d451a7540411d 100644 --- a/packages/scripts/utils/test/index.js +++ b/packages/scripts/utils/test/index.js @@ -1,22 +1,11 @@ -jest.mock( '../package', () => { - const module = require.requireActual( '../package' ); - - jest.spyOn( module, 'getPackagePath' ); - - return module; -} ); -jest.mock( '../process', () => { - const module = require.requireActual( '../process' ); - - jest.spyOn( module, 'exit' ); - jest.spyOn( module, 'getCliArgs' ); +/** + * External dependencies + */ +import crossSpawn from 'cross-spawn'; - return module; -} ); /** * Internal dependencies */ -import crossSpawn from 'cross-spawn'; import { hasCliArg, hasProjectFile, @@ -30,6 +19,22 @@ import { getCliArgs as getCliArgsMock, } from '../process'; +jest.mock( '../package', () => { + const module = require.requireActual( '../package' ); + + jest.spyOn( module, 'getPackagePath' ); + + return module; +} ); +jest.mock( '../process', () => { + const module = require.requireActual( '../process' ); + + jest.spyOn( module, 'exit' ); + jest.spyOn( module, 'getCliArgs' ); + + return module; +} ); + describe( 'utils', () => { const crossSpawnMock = jest.spyOn( crossSpawn, 'sync' ); diff --git a/packages/shortcode/src/index.js b/packages/shortcode/src/index.js index 56d97f855afd4..d9a3de767d97a 100644 --- a/packages/shortcode/src/index.js +++ b/packages/shortcode/src/index.js @@ -1,5 +1,5 @@ /** - * Internal dependencies + * External dependencies */ import { extend, pick, isString, isEqual, forEach, isNumber } from 'lodash'; import memize from 'memize'; diff --git a/packages/wordcount/src/index.js b/packages/wordcount/src/index.js index a20fefefea630..8d70df55f0a27 100644 --- a/packages/wordcount/src/index.js +++ b/packages/wordcount/src/index.js @@ -1,4 +1,11 @@ +/** + * External dependencies + */ import { extend, flow } from 'lodash'; + +/** + * Internal dependencies + */ import { defaultSettings } from './defaultSettings'; import stripTags from './stripTags'; import transposeAstralsToCountableChar from './transposeAstralsToCountableChar'; diff --git a/test/integration/is-valid-block.spec.js b/test/integration/is-valid-block.spec.js index ac969f1ecb72c..f10ef5f34d09f 100644 --- a/test/integration/is-valid-block.spec.js +++ b/test/integration/is-valid-block.spec.js @@ -1,5 +1,5 @@ /** - * External dependencies + * WordPress dependencies */ import { isValidBlockContent } from '@wordpress/blocks'; import { createElement } from '@wordpress/element'; diff --git a/test/unit/__mocks__/@wordpress/data.js b/test/unit/__mocks__/@wordpress/data.js index 1de2900bc8b20..729e53648b211 100644 --- a/test/unit/__mocks__/@wordpress/data.js +++ b/test/unit/__mocks__/@wordpress/data.js @@ -1,3 +1,8 @@ +/** + * Internal dependencies + */ import { use, plugins } from '../../../../packages/data/src'; + use( plugins.controls ); + export * from '../../../../packages/data/src';