From 3d2d2a9da7862b02b4623c830e5a528c52544d10 Mon Sep 17 00:00:00 2001 From: Rickard Laurin Date: Fri, 11 Oct 2019 08:30:34 +0200 Subject: [PATCH] feat: add eslint (#59) --- src/commands/add.ts | 21 +++++-- src/commands/init.ts | 11 +++- src/index.ts | 16 ++++- src/templates/eslint/eslintrc.node.ejs | 6 ++ src/templates/eslint/eslintrc.react.ejs | 23 +++++++ src/tools/index.ts | 28 +++++++++ test/commands/add.spec.ts | 7 +++ test/commands/init.spec.ts | 7 +++ test/tools/index.spec.ts | 80 +++++++++++++++++++++++++ 9 files changed, 190 insertions(+), 9 deletions(-) create mode 100644 src/templates/eslint/eslintrc.node.ejs create mode 100644 src/templates/eslint/eslintrc.react.ejs diff --git a/src/commands/add.ts b/src/commands/add.ts index 3c4361b..77c8c64 100644 --- a/src/commands/add.ts +++ b/src/commands/add.ts @@ -1,9 +1,19 @@ -import { nvmrc, gitignore, jest, prettierrc, config, husky } from '../tools' +import { + config, + eslint, + gitignore, + husky, + jest, + nvmrc, + prettierrc, +} from '../tools' +import { CLIFlags } from '../' export type Command = | 'config' - | 'gitignore' + | 'eslint' | 'git' + | 'gitignore' | 'husky' | 'jest' | 'nvm' @@ -12,9 +22,7 @@ export type Command = interface AddProps { command: Command - flags: { - javascript: boolean - } + flags: CLIFlags } export const add = ({ command, flags }: AddProps) => { @@ -39,6 +47,9 @@ export const add = ({ command, flags }: AddProps) => { case 'husky': husky() break + case 'eslint': + eslint({ node: flags.node, react: flags.react }) + break default: console.log(`${command} is not a valid command`) } diff --git a/src/commands/init.ts b/src/commands/init.ts index 68ba651..fac71b7 100644 --- a/src/commands/init.ts +++ b/src/commands/init.ts @@ -1,4 +1,12 @@ -import { config, gitignore, jest, nvmrc, prettierrc, husky } from '../tools' +import { + config, + gitignore, + jest, + nvmrc, + prettierrc, + husky, + eslint, +} from '../tools' import { CLIFlags } from '../' interface InitProps { @@ -12,4 +20,5 @@ export const init = async ({ flags }: InitProps) => { await jest() await nvmrc() await husky() + await eslint({ node: flags.node, react: flags.react }) } diff --git a/src/index.ts b/src/index.ts index 1531e88..b1d318a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,10 +8,12 @@ import { snippets, SnippetLanguage, SnippetIDE } from './commands/snippets' import { graphql } from './commands/graphql' export interface CLIFlags { - javascript: boolean + examples?: boolean ide?: string + javascript: boolean language?: string - examples?: boolean + node?: boolean + react?: boolean } export interface CLIProps { @@ -70,12 +72,14 @@ const cli = meow( --ide IDE for snippets (snippets) --language Language for snippets (snippets) --examples GraphQL examples (examples) + --node ESLint node (add/init) + --react ESLint react (add/init) `, { flags: { javascript: { - type: 'boolean', default: false, + type: 'boolean', }, ide: { type: 'string', @@ -86,6 +90,12 @@ const cli = meow( examples: { type: 'boolean', }, + react: { + type: 'boolean', + }, + node: { + type: 'boolean', + }, }, } ) diff --git a/src/templates/eslint/eslintrc.node.ejs b/src/templates/eslint/eslintrc.node.ejs new file mode 100644 index 0000000..378ae0b --- /dev/null +++ b/src/templates/eslint/eslintrc.node.ejs @@ -0,0 +1,6 @@ +{ + "extends": [ + "@iteam/eslint-config-node", + ] +} + diff --git a/src/templates/eslint/eslintrc.react.ejs b/src/templates/eslint/eslintrc.react.ejs new file mode 100644 index 0000000..ae1ea7c --- /dev/null +++ b/src/templates/eslint/eslintrc.react.ejs @@ -0,0 +1,23 @@ +{ + "extends": ["@iteam/eslint-config-react"], + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint"], + "parserOptions": { + "ecmaFeatures": { + "modules": true + }, + "ecmaVersion": 8, + "sourceType": "module" + }, + "overrides": [ + { + "files": ["**/*.tsx", "**/*.ts"], + "rules": { + "no-undef": "off", + "no-unused-vars": "off", + "react/prop-types": "off" + } + } + ] +} + diff --git a/src/tools/index.ts b/src/tools/index.ts index 29bbc64..33a8511 100644 --- a/src/tools/index.ts +++ b/src/tools/index.ts @@ -126,3 +126,31 @@ export const husky = async (options: ToolProps = {}) => { output: options.cwd ? `${options.cwd}/.huskyrc` : '.huskyrc', }) } + +interface EslintFlags extends ToolProps { + node?: boolean + react?: boolean +} + +export const eslint = async (options: EslintFlags = {}) => { + await installPkg('eslint', options) + + if (options.node) { + await installPkg('@iteam/eslint-config-node', options) + + await create({ + templateName: 'eslint/eslintrc.node', + output: options.cwd ? `${options.cwd}/.eslintrc` : '.eslintrc', + }) + } + + if (options.react) { + await installPkg('@iteam/eslint-config-react', options) + await installPkg('@typescript-eslint/eslint-plugin', options) + + await create({ + templateName: 'eslint/eslintrc.react', + output: options.cwd ? `${options.cwd}/.eslintrc` : '.eslintrc', + }) + } +} diff --git a/test/commands/add.spec.ts b/test/commands/add.spec.ts index af026a3..a38b5ba 100644 --- a/test/commands/add.spec.ts +++ b/test/commands/add.spec.ts @@ -6,6 +6,7 @@ import { prettierrc, config, husky, + eslint, } from '../../src/tools' jest.mock('../../src/tools') @@ -62,6 +63,12 @@ test('husky - setup', () => { expect(husky).toHaveBeenCalled() }) +test('eslint - setup', () => { + add({ command: 'eslint', flags: { node: true } }) + + expect(eslint).toHaveBeenCalledWith({ node: true }) +}) + test('handles unknown command', () => { add({ command: '__not_valid__', flags: { javascript: false } }) diff --git a/test/commands/init.spec.ts b/test/commands/init.spec.ts index da65721..6786139 100644 --- a/test/commands/init.spec.ts +++ b/test/commands/init.spec.ts @@ -6,6 +6,7 @@ import { prettierrc, nvmrc, husky, + eslint, } from '../../src/tools' jest.mock('../../src/tools') @@ -56,4 +57,10 @@ describe('#init', () => { expect(husky).toHaveBeenCalled() }) + + test('should init eslint', async () => { + await init({ flags: { node: true } }) + + expect(eslint).toHaveBeenCalledWith({ node: true }) + }) }) diff --git a/test/tools/index.spec.ts b/test/tools/index.spec.ts index 2c0f7e2..da773d2 100644 --- a/test/tools/index.spec.ts +++ b/test/tools/index.spec.ts @@ -5,6 +5,7 @@ import { nvmrc, config, husky, + eslint, } from '../../src/tools' import { create, @@ -322,6 +323,7 @@ describe('#husky', () => { output: '.huskyrc', }) }) + test('creates a config in a sub folder', async () => { await husky({ cwd: 'test' }) @@ -331,3 +333,81 @@ describe('#husky', () => { }) }) }) + +describe('#eslint', () => { + test('installs eslint', async () => { + await eslint({ cwd: 'test' }) + + expect(installPkg).toHaveBeenCalledWith('eslint', { cwd: 'test' }) + }) + + describe('Node', () => { + test('installs eslint node config', async () => { + await eslint({ cwd: 'test', node: true }) + + expect(installPkg).toHaveBeenCalledWith('@iteam/eslint-config-node', { + cwd: 'test', + node: true, + }) + }) + + test('creates a config', async () => { + await eslint({ node: true }) + + expect(create).toHaveBeenCalledWith({ + templateName: 'eslint/eslintrc.node', + output: '.eslintrc', + }) + }) + + test('creates a config in a sub folder', async () => { + await eslint({ cwd: 'test', node: true }) + + expect(create).toHaveBeenCalledWith({ + templateName: 'eslint/eslintrc.node', + output: 'test/.eslintrc', + }) + }) + }) + + describe('React', () => { + test('installs eslint react config', async () => { + await eslint({ cwd: 'test', react: true }) + + expect(installPkg).toHaveBeenCalledWith('@iteam/eslint-config-react', { + cwd: 'test', + react: true, + }) + }) + + test('installs typescript eslint plugin', async () => { + await eslint({ cwd: 'test', react: true }) + + expect(installPkg).toHaveBeenCalledWith( + '@typescript-eslint/eslint-plugin', + { + cwd: 'test', + react: true, + } + ) + }) + + test('creates a config', async () => { + await eslint({ react: true }) + + expect(create).toHaveBeenCalledWith({ + templateName: 'eslint/eslintrc.react', + output: '.eslintrc', + }) + }) + + test('creates a config in a sub folder', async () => { + await eslint({ cwd: 'test', react: true }) + + expect(create).toHaveBeenCalledWith({ + templateName: 'eslint/eslintrc.react', + output: 'test/.eslintrc', + }) + }) + }) +})