mirror of
https://github.com/coder/coder.git
synced 2025-07-09 11:45:56 +00:00
chore: Add linter for typescript code (#45)
- Add and configure `eslint` - Add to build pipeline - Fix lint failures
This commit is contained in:
122
.eslintrc.yaml
Normal file
122
.eslintrc.yaml
Normal file
@ -0,0 +1,122 @@
|
||||
---
|
||||
env:
|
||||
browser: true
|
||||
commonjs: true
|
||||
es6: true
|
||||
jest: true
|
||||
node: true
|
||||
extends:
|
||||
- eslint:recommended
|
||||
- plugin:@typescript-eslint/recommended
|
||||
- plugin:import/recommended
|
||||
- plugin:import/typescript
|
||||
- plugin:react/recommended
|
||||
- plugin:jsx-a11y/strict
|
||||
- plugin:compat/recommended
|
||||
- prettier
|
||||
parser: "@typescript-eslint/parser"
|
||||
parserOptions:
|
||||
ecmaVersion: 2018
|
||||
project:
|
||||
- "./tsconfig.json"
|
||||
- "./site/tsconfig.json"
|
||||
sourceType: module
|
||||
ecmaFeatures:
|
||||
jsx: true
|
||||
tsconfigRootDir: "./"
|
||||
plugins:
|
||||
- "@typescript-eslint"
|
||||
- import
|
||||
- react-hooks
|
||||
- jest
|
||||
- no-storage
|
||||
root: true
|
||||
rules:
|
||||
"@typescript-eslint/brace-style":
|
||||
["error", "1tbs", { "allowSingleLine": false }]
|
||||
"@typescript-eslint/camelcase": "off"
|
||||
"@typescript-eslint/explicit-function-return-type": "off"
|
||||
"@typescript-eslint/explicit-module-boundary-types": "error"
|
||||
"@typescript-eslint/method-signature-style": ["error", "property"]
|
||||
"@typescript-eslint/no-invalid-void-type": error
|
||||
# We're disabling the `no-namespace` rule to use a pattern of defining an interface,
|
||||
# and then defining functions that operate on that data via namespace. This is helpful for
|
||||
# dealing with immutable objects. This is a common pattern that shows up in some other
|
||||
# large TypeScript projects, like VSCode.
|
||||
# More details: https://github.com/coder/m/pull/9720#discussion_r697609528
|
||||
"@typescript-eslint/no-namespace": "off"
|
||||
"@typescript-eslint/no-unnecessary-boolean-literal-compare": error
|
||||
"@typescript-eslint/no-unnecessary-condition": warn
|
||||
"@typescript-eslint/no-unnecessary-type-assertion": warn
|
||||
"@typescript-eslint/no-unused-vars":
|
||||
- error
|
||||
- argsIgnorePattern: "^_"
|
||||
varsIgnorePattern: "^_"
|
||||
"@typescript-eslint/no-use-before-define": "off"
|
||||
"@typescript-eslint/object-curly-spacing": ["error", "always"]
|
||||
"@typescript-eslint/triple-slash-reference": "off"
|
||||
"brace-style": "off"
|
||||
"curly": ["error", "all"]
|
||||
eqeqeq: error
|
||||
import/default: "off"
|
||||
import/namespace: "off"
|
||||
import/newline-after-import:
|
||||
- error
|
||||
- count: 1
|
||||
import/no-named-as-default: "off"
|
||||
import/no-named-as-default-member: "off"
|
||||
import/prefer-default-export: "off"
|
||||
jest/no-focused-tests: "error"
|
||||
jsx-a11y/label-has-for: "off"
|
||||
jsx-a11y/no-autofocus: "off"
|
||||
no-console:
|
||||
- warn
|
||||
- allow:
|
||||
- warn
|
||||
- error
|
||||
- info
|
||||
- debug
|
||||
no-dupe-class-members: "off"
|
||||
no-restricted-imports:
|
||||
- error
|
||||
- paths:
|
||||
- name: "@material-ui/core"
|
||||
message:
|
||||
"Use path imports to avoid pulling in unused modules. See:
|
||||
https://material-ui.com/guides/minimizing-bundle-size/"
|
||||
- name: "@material-ui/icons"
|
||||
message:
|
||||
"Use path imports to avoid pulling in unused modules. See:
|
||||
https://material-ui.com/guides/minimizing-bundle-size/"
|
||||
- name: "@material-ui/styles"
|
||||
message:
|
||||
"Use path imports to avoid pulling in unused modules. See:
|
||||
https://material-ui.com/guides/minimizing-bundle-size/"
|
||||
- name: "@material-ui/core/Tooltip"
|
||||
message: "Use the custom Tooltip on componens/Tooltip"
|
||||
no-storage/no-browser-storage: error
|
||||
no-unused-vars: "off"
|
||||
"object-curly-spacing": "off"
|
||||
react-hooks/exhaustive-deps: warn
|
||||
react-hooks/rules-of-hooks: error
|
||||
react/jsx-no-script-url:
|
||||
- error
|
||||
- - name: Link
|
||||
props:
|
||||
- to
|
||||
- name: Button
|
||||
props:
|
||||
- href
|
||||
- name: IconButton
|
||||
props:
|
||||
- href
|
||||
react/prop-types: "off"
|
||||
react/jsx-boolean-value: ["error", "never"]
|
||||
react/jsx-curly-brace-presence:
|
||||
- error
|
||||
- children: ignore
|
||||
settings:
|
||||
react:
|
||||
version: detect
|
||||
import/resolver:
|
||||
typescript: {}
|
22
.github/workflows/coder.yaml
vendored
22
.github/workflows/coder.yaml
vendored
@ -38,6 +38,28 @@ jobs:
|
||||
with:
|
||||
version: latest
|
||||
|
||||
style-lint-typescript:
|
||||
name: "style/lint/typescript"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Cache Node
|
||||
id: cache-node
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
**/node_modules
|
||||
.eslintcache
|
||||
key: js-${{ runner.os }}-test-${{ hashFiles('**/yarn.lock') }}
|
||||
|
||||
- name: Install node_modules
|
||||
run: yarn install
|
||||
|
||||
- name: "yarn lint"
|
||||
run: yarn lint
|
||||
|
||||
gen:
|
||||
name: "style/gen"
|
||||
runs-on: ubuntu-latest
|
||||
|
13
jest-runner.eslint.config.js
Normal file
13
jest-runner.eslint.config.js
Normal file
@ -0,0 +1,13 @@
|
||||
// Toggle eslint --fix by specifying the `FIX` env.
|
||||
const fix = !!process.env.FIX
|
||||
|
||||
module.exports = {
|
||||
cliOptions: {
|
||||
ext: [".js", ".ts", ".tsx"],
|
||||
ignorePath: ".eslintignore",
|
||||
cache: false,
|
||||
fix,
|
||||
resolvePluginsRelativeTo: ".",
|
||||
maxWarnings: 0,
|
||||
},
|
||||
}
|
@ -13,6 +13,12 @@ module.exports = {
|
||||
testPathIgnorePatterns: ["/node_modules/", "/__tests__/fakes"],
|
||||
moduleDirectories: ["node_modules", "<rootDir>"],
|
||||
},
|
||||
{
|
||||
displayName: "lint",
|
||||
runner: "jest-runner-eslint",
|
||||
testMatch: ["<rootDir>/site/**/*.js", "<rootDir>/site/**/*.ts", "<rootDir>/site/**/*.tsx"],
|
||||
testPathIgnorePatterns: ["/.next/", "/out/"],
|
||||
},
|
||||
],
|
||||
collectCoverageFrom: [
|
||||
"<rootDir>/site/**/*.js",
|
||||
|
16
package.json
16
package.json
@ -10,6 +10,8 @@
|
||||
"export": "next export site",
|
||||
"format:check": "prettier --check '**/*.{css,html,js,json,jsx,md,ts,tsx,yaml,yml}'",
|
||||
"format:write": "prettier --write '**/*.{css,html,js,json,jsx,md,ts,tsx,yaml,yml}' && sql-formatter -l postgresql ./database/query.sql -o ./database/query.sql",
|
||||
"lint": "jest --selectProjects lint",
|
||||
"lint:fix": "FIX=true yarn lint",
|
||||
"test": "jest --selectProjects test",
|
||||
"test:coverage": "jest --selectProjects test --collectCoverage"
|
||||
},
|
||||
@ -24,9 +26,23 @@
|
||||
"@types/react": "17.0.38",
|
||||
"@types/react-dom": "17.0.11",
|
||||
"@types/superagent": "4.1.14",
|
||||
"@typescript-eslint/eslint-plugin": "4.33.0",
|
||||
"@typescript-eslint/parser": "4.33.0",
|
||||
"eslint": "7.32.0",
|
||||
"eslint-config-prettier": "8.3.0",
|
||||
"eslint-import-resolver-alias": "1.1.2",
|
||||
"eslint-import-resolver-typescript": "2.5.0",
|
||||
"eslint-plugin-compat": "4.0.1",
|
||||
"eslint-plugin-import": "2.25.4",
|
||||
"eslint-plugin-jest": "25.7.0",
|
||||
"eslint-plugin-jsx-a11y": "6.5.1",
|
||||
"eslint-plugin-no-storage": "1.0.2",
|
||||
"eslint-plugin-react": "7.28.0",
|
||||
"eslint-plugin-react-hooks": "4.3.0",
|
||||
"express": "4.17.2",
|
||||
"http-proxy-middleware": "2.0.1",
|
||||
"jest": "27.4.7",
|
||||
"jest-runner-eslint": "1.0.0",
|
||||
"next": "12.0.7",
|
||||
"prettier": "2.5.1",
|
||||
"react": "17.0.2",
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { screen } from "@testing-library/react"
|
||||
import { render } from "../../test_helpers"
|
||||
import React from "react"
|
||||
import { EmptyState, EmptyStateProps } from "./index"
|
||||
import { EmptyState } from "./index"
|
||||
|
||||
describe("EmptyState", () => {
|
||||
it("renders (smoke test)", async () => {
|
||||
|
@ -1,12 +1,12 @@
|
||||
import React from "react"
|
||||
import { SvgIcon } from "@material-ui/core"
|
||||
import SvgIcon from "@material-ui/core/SvgIcon"
|
||||
import { render } from "./../../test_helpers"
|
||||
|
||||
import * as Icons from "./index"
|
||||
|
||||
const getAllIcons = (): [string, typeof SvgIcon][] => {
|
||||
let k: keyof typeof Icons
|
||||
let ret: [string, typeof SvgIcon][] = []
|
||||
const ret: [string, typeof SvgIcon][] = []
|
||||
for (k in Icons) {
|
||||
ret.push([k, Icons[k]])
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
import React from "react"
|
||||
import Button from "@material-ui/core/Button"
|
||||
import List from "@material-ui/core/List"
|
||||
import ListSubheader from "@material-ui/core/ListSubheader"
|
||||
import { makeStyles } from "@material-ui/core/styles"
|
||||
import { Button, List, ListSubheader } from "@material-ui/core"
|
||||
|
||||
import Link from "next/link"
|
||||
|
||||
|
@ -10,7 +10,7 @@ module.exports = {
|
||||
// Allows us to import TS files from outside product/coder/site.
|
||||
externalDir: true,
|
||||
},
|
||||
webpack: (config, { dev, isServer, webpack }) => {
|
||||
webpack: (config, { isServer, webpack }) => {
|
||||
// Inject CODERD_HOST environment variable for clients
|
||||
if (!isServer) {
|
||||
config.plugins.push(
|
||||
|
@ -1,11 +1,10 @@
|
||||
import React from "react"
|
||||
|
||||
import CssBaseline from "@material-ui/core/CssBaseline"
|
||||
import { makeStyles } from "@material-ui/core/styles"
|
||||
import ThemeProvider from "@material-ui/styles/ThemeProvider"
|
||||
|
||||
import { dark } from "../theme"
|
||||
import { AppProps } from "next/app"
|
||||
import { makeStyles } from "@material-ui/core"
|
||||
import { Navbar } from "../components/Navbar"
|
||||
import { Footer } from "../components/Page"
|
||||
|
||||
@ -64,7 +63,7 @@ const MyApp: React.FC<AppProps> = (appProps) => {
|
||||
)
|
||||
}
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
const useStyles = makeStyles(() => ({
|
||||
root: {
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
|
@ -1,6 +1,8 @@
|
||||
import React from "react"
|
||||
import { makeStyles, Box, Paper } from "@material-ui/core"
|
||||
import { AddToQueue as AddWorkspaceIcon } from "@material-ui/icons"
|
||||
import Box from "@material-ui/core/Box"
|
||||
import { makeStyles } from "@material-ui/core/styles"
|
||||
import Paper from "@material-ui/core/Paper"
|
||||
import AddWorkspaceIcon from "@material-ui/icons/AddToQueue"
|
||||
|
||||
import { EmptyState, SplitButton } from "../components"
|
||||
|
||||
|
@ -4,9 +4,6 @@ import { CustomPalette, darkPalette, lightPalette } from "./palettes"
|
||||
import { typography } from "./typography"
|
||||
|
||||
const makeTheme = (palette: CustomPalette) => {
|
||||
// Grab defaults to re-use in overrides
|
||||
const { breakpoints } = createMuiTheme()
|
||||
|
||||
return createMuiTheme({
|
||||
palette,
|
||||
typography,
|
||||
|
Reference in New Issue
Block a user