From cfb372f75a8ef3b12bca521873b3b3bcf009017b Mon Sep 17 00:00:00 2001 From: Harrison Healey Date: Thu, 11 Oct 2018 13:35:25 -0400 Subject: [PATCH] MM-11157 Switch ESLint to use eslint-config-mattermost (#2247) --- .editorconfig | 2 +- .eslintrc.json | 301 ++---------------- app/actions/views/channel.js | 2 +- app/actions/views/command.js | 4 +- .../file_attachment_list.js | 4 +- app/fetch_preconfig.js | 2 + app/screens/channel/channel.js | 2 +- .../channel_nav_bar/channel_drawer_button.js | 4 +- .../channel_add_members.js | 2 +- .../channel_members/channel_members.js | 2 +- .../menu_action_selector.js | 2 +- app/screens/more_channels/more_channels.js | 2 +- app/screens/more_dms/more_dms.js | 2 +- app/utils/general.js | 4 +- package-lock.json | 5 + package.json | 1 + .../android/extension_post/extension_post.js | 2 +- share_extension/ios/extension_post.js | 2 +- 18 files changed, 54 insertions(+), 291 deletions(-) diff --git a/.editorconfig b/.editorconfig index a58a373c5..be3c34776 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,7 +11,7 @@ charset = utf-8 indent_style = space indent_size = 4 -[webapp/package.json] +[{package.json,.eslintrc.json}] indent_size = 2 [Makefile] diff --git a/.eslintrc.json b/.eslintrc.json index a275ca7ef..607bf3427 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,276 +1,31 @@ { - "extends": [ - "eslint:recommended", - "plugin:react/recommended" - ], - "parserOptions": { - "ecmaVersion": 6, - "sourceType": "module", - "ecmaFeatures": { - "jsx": true, - "impliedStrict": true, - "modules": true - } - }, - "parser": "babel-eslint", - "settings": { - "react": { - "pragma": "React", - "version": "16.5" - } - }, - "plugins": [ - "react", - "header" - ], - "env": { - "browser": true, - "node": true, - "jquery": true, - "es6": true, - "jest": true - }, - "globals": { - "after": true, - "afterAll": true, - "afterEach": true, - "before": true, - "beforeAll": true, - "beforeEach": true, - "describe": true, - "expect": true, - "it": true, - "jest": true, - "test": true, - "__DEV__": true - }, - "rules": { - "array-bracket-spacing": [2, "never"], - "array-callback-return": 2, - "arrow-body-style": 0, - "arrow-parens": [2, "always"], - "arrow-spacing": [2, { "before": true, "after": true }], - "block-scoped-var": 2, - "brace-style": [2, "1tbs", { "allowSingleLine": false }], - "camelcase": [2, {"properties": "never"}], - "class-methods-use-this": 0, - "comma-dangle": [2, "always-multiline"], - "comma-spacing": [2, {"before": false, "after": true}], - "comma-style": [2, "last"], - "complexity": [0, 10], - "computed-property-spacing": [2, "never"], - "consistent-return": 2, - "consistent-this": [2, "self"], - "constructor-super": 2, - "curly": [2, "all"], - "dot-location": [2, "object"], - "dot-notation": 2, - "eqeqeq": [2, "smart"], - "func-call-spacing": [2, "never"], - "func-names": 2, - "func-style": [2, "declaration", { "allowArrowFunctions": true }], - "generator-star-spacing": [0, {"before": false, "after": true}], - "global-require": 0, - "guard-for-in": 2, - "header/header": [2, "line", " Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n See LICENSE.txt for license information."], - "id-blacklist": 0, - "indent": [2, 4, {"SwitchCase": 0}], - "jsx-quotes": [2, "prefer-single"], - "key-spacing": [2, {"beforeColon": false, "afterColon": true, "mode": "strict"}], - "keyword-spacing": [2, {"before": true, "after": true, "overrides": {}}], - "line-comment-position": 0, - "linebreak-style": 2, - "lines-around-comment": [2, { "beforeBlockComment": true, "beforeLineComment": true, "allowBlockStart": true, "allowBlockEnd": true }], - "max-lines": [1, {"max": 450, "skipBlankLines": true, "skipComments": false}], - "max-nested-callbacks": [2, {"max":2}], - "max-statements-per-line": [2, {"max": 1}], - "multiline-ternary": [1, "never"], - "new-cap": 2, - "new-parens": 2, - "newline-before-return": 0, - "newline-per-chained-call": 0, - "no-alert": 2, - "no-array-constructor": 2, - "no-caller": 2, - "no-case-declarations": 2, - "no-class-assign": 2, - "no-cond-assign": [2, "except-parens"], - "no-confusing-arrow": 2, - "no-console": 2, - "no-const-assign": 2, - "no-constant-condition": 2, - "no-debugger": 2, - "no-div-regex": 2, - "no-dupe-args": 2, - "no-dupe-class-members": 2, - "no-dupe-keys": 2, - "no-duplicate-case": 2, - "no-duplicate-imports": [2, {"includeExports": true}], - "no-else-return": 2, - "no-empty": 2, - "no-empty-function": 2, - "no-empty-pattern": 2, - "no-eval": 2, - "no-ex-assign": 2, - "no-extend-native": 2, - "no-extra-bind": 2, - "no-extra-label": 2, - "no-extra-parens": 0, - "no-extra-semi": 2, - "no-fallthrough": 2, - "no-floating-decimal": 2, - "no-func-assign": 2, - "no-global-assign": 2, - "no-implicit-coercion": 2, - "no-implicit-globals": 0, - "no-implied-eval": 2, - "no-inner-declarations": 0, - "no-invalid-regexp": 2, - "no-irregular-whitespace": 2, - "no-iterator": 2, - "no-labels": 2, - "no-lone-blocks": 2, - "no-lonely-if": 2, - "no-loop-func": 2, - "no-magic-numbers": 0, - "no-mixed-operators": [2, {"allowSamePrecedence": false}], - "no-mixed-spaces-and-tabs": 2, - "no-multi-spaces": [2, { "exceptions": { "Property": false } }], - "no-multi-str": 0, - "no-multiple-empty-lines": [2, {"max": 1}], - "no-native-reassign": 2, - "no-negated-condition": 2, - "no-nested-ternary": 2, - "no-new": 2, - "no-new-func": 2, - "no-new-object": 2, - "no-new-symbol": 2, - "no-new-wrappers": 2, - "no-octal-escape": 2, - "no-param-reassign": 2, - "no-process-env": 2, - "no-process-exit": 2, - "no-proto": 2, - "no-redeclare": 2, - "no-return-assign": [2, "always"], - "no-script-url": 2, - "no-self-assign": [2, {"props": true}], - "no-self-compare": 2, - "no-sequences": 2, - "no-shadow": [2, {"hoist": "functions"}], - "no-shadow-restricted-names": 2, - "no-spaced-func": 2, - "no-tabs": 0, - "no-template-curly-in-string": 2, - "no-ternary": 0, - "no-this-before-super": 2, - "no-throw-literal": 0, - "no-trailing-spaces": [2, { "skipBlankLines": false }], - "no-undef-init": 2, - "no-undefined": 2, - "no-underscore-dangle": 2, - "no-unexpected-multiline": 2, - "no-unmodified-loop-condition": 2, - "no-unneeded-ternary": [2, {"defaultAssignment": false}], - "no-unreachable": 2, - "no-unsafe-finally": 2, - "no-unsafe-negation": 2, - "no-unused-expressions": 2, - "no-unused-vars": [2, {"vars": "all", "args": "after-used"}], - "no-use-before-define": [2, {"classes": false, "functions": false, "variables": false}], - "no-useless-computed-key": 2, - "no-useless-concat": 2, - "no-useless-constructor": 2, - "no-useless-escape": 2, - "no-useless-rename": 2, - "no-var": 0, - "no-void": 2, - "no-warning-comments": 1, - "no-whitespace-before-property": 2, - "no-with": 2, - "object-curly-newline": 0, - "object-curly-spacing": [2, "never"], - "object-property-newline": [2, {"allowMultiplePropertiesPerLine": true}], - "object-shorthand": [2, "always"], - "one-var": [2, "never"], - "one-var-declaration-per-line": 0, - "operator-linebreak": [2, "after"], - "padded-blocks": [2, "never"], - "prefer-arrow-callback": 2, - "prefer-const": 2, - "prefer-numeric-literals": 2, - "prefer-reflect": 2, - "prefer-rest-params": 2, - "prefer-spread": 2, - "prefer-template": 0, - "quote-props": [2, "as-needed"], - "quotes": [2, "single", "avoid-escape"], - "radix": 2, - "react/display-name": [2, { "ignoreTranspilerName": false }], - "react/jsx-boolean-value": [2, "always"], - "react/jsx-closing-bracket-location": [2, { "location": "tag-aligned" }], - "react/jsx-curly-spacing": [2, "never"], - "react/jsx-equals-spacing": [2, "never"], - "react/jsx-filename-extension": [2, {"extensions": [".js"]}], - "react/jsx-first-prop-new-line": [2, "multiline"], - "react/jsx-handler-names": 0, - "react/jsx-indent": [2, 4], - "react/jsx-indent-props": [2, 4], - "react/jsx-key": 2, - "react/jsx-max-props-per-line": [2, { "maximum": 1 }], - "react/jsx-no-bind": 0, - "react/jsx-no-duplicate-props": [2, { "ignoreCase": false }], - "react/jsx-no-literals": 2, - "react/jsx-no-target-blank": 2, - "react/jsx-no-undef": 2, - "react/jsx-pascal-case": 2, - "react/jsx-tag-spacing": [2, {"closingSlash": "never", "beforeSelfClosing": "never", "afterOpening": "never"}], - "react/jsx-uses-react": 2, - "react/jsx-uses-vars": 2, - "react/jsx-no-comment-textnodes": 2, - "react/no-danger": 0, - "react/no-deprecated": 1, - "react/no-did-mount-set-state": 2, - "react/no-did-update-set-state": 2, - "react/no-direct-mutation-state": 2, - "react/no-is-mounted": 2, - "react/no-multi-comp": [2, { "ignoreStateless": true }], - "react/no-render-return-value": 2, - "react/no-set-state": 0, - "react/no-string-refs": 0, - "react/no-unknown-property": 2, - "react/prefer-es6-class": 2, - "react/prefer-stateless-function": 0, - "react/prop-types": 2, - "react/require-optimization": 1, - "react/require-render-return": 2, - "react/self-closing-comp": 2, - "react/sort-comp": 0, - "react/jsx-wrap-multilines": 2, - "react/no-find-dom-node": 1, - "react/forbid-component-props": 0, - "react/no-danger-with-children": 2, - "react/no-unused-prop-types": [1, {"skipShapeProps": true}], - "react/style-prop-object": 2, - "react/no-children-prop": 2, - "react/no-unescaped-entities": 2, - "require-yield": 2, - "rest-spread-spacing": [2, "never"], - "semi": [2, "always"], - "semi-spacing": [2, {"before": false, "after": true}], - "sort-imports": 0, - "sort-keys": 0, - "space-before-blocks": [2, "always"], - "space-before-function-paren": [2, {"anonymous": "never", "named": "never", "asyncArrow": "always"}], - "space-in-parens": [2, "never"], - "space-infix-ops": 2, - "space-unary-ops": [2, { "words": true, "nonwords": false }], - "symbol-description": 2, - "template-curly-spacing": [2, "never"], - "valid-typeof": [2, {"requireStringLiterals": false}], - "vars-on-top": 0, - "wrap-iife": [2, "outside"], - "wrap-regex": 2, - "yoda": [2, "never", {"exceptRange": false, "onlyEquality": false}] + "extends": [ + "./node_modules/eslint-config-mattermost/.eslintrc.json", + "./node_modules/eslint-config-mattermost/.eslintrc-react.json" + ], + "settings": { + "react": { + "pragma": "React", + "version": "16.5" } + }, + "env": { + "jest": true + }, + "globals": { + "__DEV__": true + }, + "rules": { + "global-require": 0, + "react/display-name": [2, { "ignoreTranspilerName": false }], + "react/jsx-filename-extension": [2, {"extensions": [".js"]}] + }, + "overrides": [ + { + "files": ["*.test.js", "*.test.jsx"], + "env": { + "jest": true + } + } + ] } diff --git a/app/actions/views/channel.js b/app/actions/views/channel.js index 55e529bcf..126cd5e29 100644 --- a/app/actions/views/channel.js +++ b/app/actions/views/channel.js @@ -209,7 +209,7 @@ export function loadPostsIfNecessaryWithRetry(channelId) { export async function retryGetPostsAction(action, dispatch, getState, maxTries = MAX_POST_TRIES) { for (let i = 0; i < maxTries; i++) { - const {data} = await dispatch(action); + const {data} = await dispatch(action); // eslint-disable-line no-await-in-loop if (data) { dispatch(setChannelRetryFailed(false)); diff --git a/app/actions/views/command.js b/app/actions/views/command.js index 0e57b67ce..cad181e88 100644 --- a/app/actions/views/command.js +++ b/app/actions/views/command.js @@ -27,6 +27,6 @@ export function executeCommand(message, channelId, rootId) { const cmd = msg.substring(0, cmdLength).toLowerCase(); msg = cmd + msg.substring(cmdLength, msg.length); - return await executeCommandService(msg, args)(dispatch, getState); + return executeCommandService(msg, args)(dispatch, getState); }; -} \ No newline at end of file +} diff --git a/app/components/file_attachment_list/file_attachment_list.js b/app/components/file_attachment_list/file_attachment_list.js index 3fbec8455..b9142ccbc 100644 --- a/app/components/file_attachment_list/file_attachment_list.js +++ b/app/components/file_attachment_list/file_attachment_list.js @@ -95,9 +95,9 @@ export default class FileAttachmentList extends Component { if (file.localPath) { uri = file.localPath; } else if (isGif(file)) { - cache = await getCacheFile(file.name, Client4.getFileUrl(file.id)); + cache = await getCacheFile(file.name, Client4.getFileUrl(file.id)); // eslint-disable-line no-await-in-loop } else { - cache = await getCacheFile(file.name, Client4.getFilePreviewUrl(file.id)); + cache = await getCacheFile(file.name, Client4.getFilePreviewUrl(file.id)); // eslint-disable-line no-await-in-loop } if (cache) { diff --git a/app/fetch_preconfig.js b/app/fetch_preconfig.js index 276c94d0f..38ea9992c 100644 --- a/app/fetch_preconfig.js +++ b/app/fetch_preconfig.js @@ -12,6 +12,8 @@ import LocalConfig from 'assets/config'; import {t} from 'app/utils/i18n'; +/* eslint-disable no-throw-literal */ + const HEADER_X_CLUSTER_ID = 'X-Cluster-Id'; const HEADER_TOKEN = 'Token'; diff --git a/app/screens/channel/channel.js b/app/screens/channel/channel.js index 5dc07ae7f..e3d027b89 100644 --- a/app/screens/channel/channel.js +++ b/app/screens/channel/channel.js @@ -163,7 +163,7 @@ export default class Channel extends PureComponent { top = ANDROID_TOP_LANDSCAPE; } else { top = ANDROID_TOP_PORTRAIT; - height = (height - 84); + height -= 84; } break; case 'ios': diff --git a/app/screens/channel/channel_nav_bar/channel_drawer_button.js b/app/screens/channel/channel_nav_bar/channel_drawer_button.js index fb63917ae..5fb3a44ae 100644 --- a/app/screens/channel/channel_nav_bar/channel_drawer_button.js +++ b/app/screens/channel/channel_nav_bar/channel_drawer_button.js @@ -94,8 +94,8 @@ class ChannelDrawerButton extends PureComponent { const members = Object.values(myTeamMembers).filter((m) => m.team_id !== currentTeamId); members.forEach((m) => { - mentions = mentions + (m.mention_count || 0); - messages = messages + (m.msg_count || 0); + mentions += (m.mention_count || 0); + messages += (m.msg_count || 0); }); let badgeCount = 0; diff --git a/app/screens/channel_add_members/channel_add_members.js b/app/screens/channel_add_members/channel_add_members.js index 24519976d..60d8a760f 100644 --- a/app/screens/channel_add_members/channel_add_members.js +++ b/app/screens/channel_add_members/channel_add_members.js @@ -192,7 +192,7 @@ class ChannelAddMembers extends PureComponent { const {next, searching} = this.state; let {page} = this.state; if (loadMoreRequestStatus !== RequestStatus.STARTED && next && !searching) { - page = page + 1; + page += 1; actions.getProfilesNotInChannel(currentTeam.id, currentChannel.id, page, General.PROFILE_CHUNK_SIZE).then(({data}) => { if (data && data.length) { this.setState({ diff --git a/app/screens/channel_members/channel_members.js b/app/screens/channel_members/channel_members.js index bf03d7f8d..b63a9c3ab 100644 --- a/app/screens/channel_members/channel_members.js +++ b/app/screens/channel_members/channel_members.js @@ -212,7 +212,7 @@ class ChannelMembers extends PureComponent { const {next, searching} = this.state; let {page} = this.state; if (requestStatus !== RequestStatus.STARTED && next && !searching) { - page = page + 1; + page += 1; actions.getProfilesInChannel(currentChannel.id, page, General.PROFILE_CHUNK_SIZE).then( ({data}) => { if (data && data.length) { diff --git a/app/screens/menu_action_selector/menu_action_selector.js b/app/screens/menu_action_selector/menu_action_selector.js index 7dd3cef50..28b2b583f 100644 --- a/app/screens/menu_action_selector/menu_action_selector.js +++ b/app/screens/menu_action_selector/menu_action_selector.js @@ -116,7 +116,7 @@ class MenuActionSelector extends PureComponent { let {page} = this.state; if (loadMoreRequestStatus !== RequestStatus.STARTED && next && !searching) { - page = page + 1; + page += 1; let results; if (dataSource === ViewTypes.DATA_SOURCE_USERS) { diff --git a/app/screens/more_channels/more_channels.js b/app/screens/more_channels/more_channels.js index b8210467d..8a7e0f810 100644 --- a/app/screens/more_channels/more_channels.js +++ b/app/screens/more_channels/more_channels.js @@ -201,7 +201,7 @@ export default class MoreChannels extends PureComponent { loadMoreChannels = () => { let {page} = this.state; if (this.props.requestStatus.status !== RequestStatus.STARTED && this.state.next && !this.state.searching) { - page = page + 1; + page += 1; this.props.actions.getChannels( this.props.currentTeamId, page, diff --git a/app/screens/more_dms/more_dms.js b/app/screens/more_dms/more_dms.js index e8688504f..81990323c 100644 --- a/app/screens/more_dms/more_dms.js +++ b/app/screens/more_dms/more_dms.js @@ -233,7 +233,7 @@ class MoreDirectMessages extends PureComponent { let {page} = this.state; if (this.props.getRequest.status !== RequestStatus.STARTED && this.state.next && !this.state.searching) { - page = page + 1; + page += 1; this.getProfiles(page).then(({data}) => { if (data && data.length) { this.setState({ diff --git a/app/utils/general.js b/app/utils/general.js index 7fc768984..825ffff1d 100644 --- a/app/utils/general.js +++ b/app/utils/general.js @@ -44,8 +44,8 @@ export function alertErrorIfInvalidPermissions(result) { } } -export function emptyFunction() { - return; +export function emptyFunction() { // eslint-disable-line no-empty-function + } export function throttle(fn, limit, ...args) { diff --git a/package-lock.json b/package-lock.json index a68230537..34d52c064 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6070,6 +6070,11 @@ } } }, + "eslint-config-mattermost": { + "version": "github:mattermost/eslint-config-mattermost#3ee77526c9c963877f3141b9c9090a236392bf82", + "from": "github:mattermost/eslint-config-mattermost", + "dev": true + }, "eslint-plugin-header": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/eslint-plugin-header/-/eslint-plugin-header-2.0.0.tgz", diff --git a/package.json b/package.json index 5df51d22c..484625373 100644 --- a/package.json +++ b/package.json @@ -87,6 +87,7 @@ "enzyme-adapter-react-16": "1.5.0", "enzyme-to-json": "3.3.4", "eslint": "5.6.0", + "eslint-config-mattermost": "github:mattermost/eslint-config-mattermost", "eslint-plugin-header": "2.0.0", "eslint-plugin-jest": "21.22.0", "eslint-plugin-react": "7.11.1", diff --git a/share_extension/android/extension_post/extension_post.js b/share_extension/android/extension_post/extension_post.js index af3c53116..0802d27c7 100644 --- a/share_extension/android/extension_post/extension_post.js +++ b/share_extension/android/extension_post/extension_post.js @@ -282,7 +282,7 @@ export default class ExtensionPost extends PureComponent { let fileSize = {size: 0}; const fullPath = item.value; try { - fileSize = await RNFetchBlob.fs.stat(fullPath); + fileSize = await RNFetchBlob.fs.stat(fullPath); // eslint-disable-line no-await-in-loop } catch (e) { const {formatMessage} = this.context.intl; error = formatMessage({ diff --git a/share_extension/ios/extension_post.js b/share_extension/ios/extension_post.js index ca09ac5b5..20c856c04 100644 --- a/share_extension/ios/extension_post.js +++ b/share_extension/ios/extension_post.js @@ -253,7 +253,7 @@ export default class ExtensionPost extends PureComponent { default: { const fullPath = item.value; const filePath = decodeURIComponent(fullPath.replace('file://', '')); - const fileSize = await RNFetchBlob.fs.stat(filePath); + const fileSize = await RNFetchBlob.fs.stat(filePath); // eslint-disable-line no-await-in-loop const filename = decodeURIComponent(fullPath.replace(/^.*[\\/]/, '')); const extension = filename.split('.').pop();