Skip to content

Commit

Permalink
Configured include and ignore directories and patterns 🚦
Browse files Browse the repository at this point in the history
  • Loading branch information
01taylop committed Jul 22, 2024
1 parent 4749797 commit 2287653
Show file tree
Hide file tree
Showing 5 changed files with 239 additions and 24 deletions.
144 changes: 144 additions & 0 deletions src/__tests__/filePatterns.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import colourLog from '@Utils/colourLog'
import { Linter } from '@Types'

import getFilePatterns from '../filePatterns'

describe('filePatterns', () => {

jest.spyOn(colourLog, 'config').mockImplementation(() => {})
jest.spyOn(console, 'log').mockImplementation(() => {})

it('returns the correct file patterns for eslint', () => {
const filePatterns = getFilePatterns({})

const expectedPatterns = [
'**/*.{cjs,js,jsx,mjs,ts,tsx}',
]

expect(filePatterns.includePatterns[Linter.ESLint]).toEqual(expectedPatterns)
expect(colourLog.config).toHaveBeenCalledWith('ESLint Patterns', expectedPatterns)
})

it('returns the correct file patterns for eslint with an additional include pattern', () => {
const filePatterns = getFilePatterns({
eslintInclude: 'foo'
})

const expectedPatterns = [
'**/*.{cjs,js,jsx,mjs,ts,tsx}',
'foo',
]

expect(filePatterns.includePatterns[Linter.ESLint]).toEqual(expectedPatterns)
expect(colourLog.config).toHaveBeenCalledWith('ESLint Patterns', expectedPatterns)
})

it('returns the correct file patterns for eslint with several additional include patterns', () => {
const filePatterns = getFilePatterns({
eslintInclude: ['foo', 'bar'],
})

const expectedPatterns = [
'**/*.{cjs,js,jsx,mjs,ts,tsx}',
'foo',
'bar',
]

expect(filePatterns.includePatterns[Linter.ESLint]).toEqual(expectedPatterns)
expect(colourLog.config).toHaveBeenCalledWith('ESLint Patterns', expectedPatterns)
})

it('returns the correct file patterns for markdownlint', () => {
const filePatterns = getFilePatterns({})

const expectedPatterns = [
'**/*.{md,mdx}',
]

expect(filePatterns.includePatterns[Linter.Markdownlint]).toEqual(expectedPatterns)
expect(colourLog.config).toHaveBeenCalledWith('Markdownlint Patterns', expectedPatterns)
})

it('returns the correct file patterns for stylelint', () => {
const filePatterns = getFilePatterns({})

const expectedPatterns = [
'**/*.{css,scss,less,sass,styl,stylus}',
]

expect(filePatterns.includePatterns[Linter.Stylelint]).toEqual(expectedPatterns)
expect(colourLog.config).toHaveBeenCalledWith('Stylelint Patterns', expectedPatterns)
})

it('returns the correct ignore file patterns', () => {
const filePatterns = getFilePatterns({})

const expectedPatterns = [
'**/+(coverage|dist|node_modules|tmp|tscOutput|vendor)/**',
'**/*.+(map|min).*',
]

expect(filePatterns.ignorePatterns).toEqual(expectedPatterns)
expect(colourLog.config).toHaveBeenCalledWith('Ignore', expectedPatterns)
})

it('returns the correct ignore file patterns with an additional directory ignored', () => {
const filePatterns = getFilePatterns({
ignoreDirs: 'foo'
})

const expectedPatterns = [
'**/+(coverage|dist|foo|node_modules|tmp|tscOutput|vendor)/**',
'**/*.+(map|min).*',
]

expect(filePatterns.ignorePatterns).toEqual(expectedPatterns)
expect(colourLog.config).toHaveBeenCalledWith('Ignore', expectedPatterns)
})

it('returns the correct ignore file patterns with several additional directories ignored', () => {
const filePatterns = getFilePatterns({
ignoreDirs: ['foo', 'bar'],
})

const expectedPatterns = [
'**/+(bar|coverage|dist|foo|node_modules|tmp|tscOutput|vendor)/**',
'**/*.+(map|min).*',
]

expect(filePatterns.ignorePatterns).toEqual(expectedPatterns)
expect(colourLog.config).toHaveBeenCalledWith('Ignore', expectedPatterns)
})

it('returns the correct ignore file patterns with an additional pattern ignored', () => {
const filePatterns = getFilePatterns({
ignorePatterns: 'foo'
})

const expectedPatterns = [
'**/+(coverage|dist|node_modules|tmp|tscOutput|vendor)/**',
'**/*.+(map|min).*',
'foo',
]

expect(filePatterns.ignorePatterns).toEqual(expectedPatterns)
expect(colourLog.config).toHaveBeenCalledWith('Ignore', expectedPatterns)
})

it('returns the correct ignore file patterns with several additional patterns ignored', () => {
const filePatterns = getFilePatterns({
ignorePatterns: ['foo', 'bar'],
})

const expectedPatterns = [
'**/+(coverage|dist|node_modules|tmp|tscOutput|vendor)/**',
'**/*.+(map|min).*',
'bar',
'foo',
]

expect(filePatterns.ignorePatterns).toEqual(expectedPatterns)
expect(colourLog.config).toHaveBeenCalledWith('Ignore', expectedPatterns)
})

})
56 changes: 56 additions & 0 deletions src/filePatterns.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { type FilePatterns, Linter } from '@Types'
import colourLog from '@Utils/colourLog'

type StringOrArray = string | Array<string>

interface GetFilePatterns {
eslintInclude?: StringOrArray
ignoreDirs?: StringOrArray
ignorePatterns?: StringOrArray
}

const enforceArray = (value: StringOrArray = []): Array<string> => Array.of(value).flat()

const getFilePatterns = ({ eslintInclude, ignoreDirs, ignorePatterns }: GetFilePatterns): FilePatterns => {
const eslintIncludePatterns = [
'**/*.{cjs,js,jsx,mjs,ts,tsx}',
...enforceArray(eslintInclude),
]

const ignoreDirectories = [
'coverage',
'dist',
'node_modules',
'tmp',
'tscOutput',
'vendor',
...enforceArray(ignoreDirs),
].sort()

const ignoreGlobs = [
'**/*.+(map|min).*',
...enforceArray(ignorePatterns),
].sort()

const filePatterns = {
includePatterns: {
[Linter.ESLint]: eslintIncludePatterns,
[Linter.Markdownlint]: ['**/*.{md,mdx}'],
[Linter.Stylelint]: ['**/*.{css,scss,less,sass,styl,stylus}'],
},
ignorePatterns: [
`**/+(${ignoreDirectories.join('|')})/**`,
...ignoreGlobs,
],
}

colourLog.config('ESLint Patterns', filePatterns.includePatterns[Linter.ESLint])
colourLog.config('Markdownlint Patterns', filePatterns.includePatterns[Linter.Markdownlint])
colourLog.config('Stylelint Patterns', filePatterns.includePatterns[Linter.Stylelint])
colourLog.config('Ignore', filePatterns.ignorePatterns)
console.log()

return filePatterns
}

export default getFilePatterns
47 changes: 26 additions & 21 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { clearTerminal } from '@Utils/terminal'

import type { LintReport, RunLinter, RunLintPilot } from '@Types'

import getFilePatterns from './filePatterns'
import linters from './linters/index'
import sourceFiles from './sourceFiles'
import { fileChangeEvent, watchFiles } from './watchFiles'
Expand All @@ -21,16 +22,13 @@ program
.addHelpText('beforeAll', '\n✈️ Lint Pilot ✈️\n')
.showHelpAfterError('\n💡 Run `lint-pilot --help` for more information.\n')

const runLinter = async ({ filePattern, linter }: RunLinter) => {
const runLinter = async ({ filePattern, linter, ignore }: RunLinter) => {
const startTime = new Date().getTime()
colourLog.info(`Running ${linter.toLowerCase()}...`)

const files = await sourceFiles({
filePattern,
ignore: [
'**/*.min.*',
'**/+(coverage|node_modules)/**',
],
ignore,
linter,
})

Expand All @@ -41,18 +39,21 @@ const runLinter = async ({ filePattern, linter }: RunLinter) => {
return report
}

const runLintPilot = ({ title, watch }: RunLintPilot) => {
const runLintPilot = ({ filePatterns, title, watch }: RunLintPilot) => {
Promise.all([
runLinter({
filePattern: '**/*.{cjs,js,jsx,mjs,ts,tsx}',
filePattern: filePatterns.includePatterns[Linter.ESLint],
ignore: filePatterns.ignorePatterns,
linter: Linter.ESLint,
}),
runLinter({
filePattern: '**/*.{md,mdx}',
filePattern: filePatterns.includePatterns[Linter.Markdownlint],
ignore: filePatterns.ignorePatterns,
linter: Linter.Markdownlint,
}),
runLinter({
filePattern: '**/*.{css,scss,less,sass,styl,stylus}',
filePattern: filePatterns.includePatterns[Linter.Stylelint],
ignore: filePatterns.ignorePatterns,
linter: Linter.Stylelint,
}),
]).then((reports) => {
Expand All @@ -78,35 +79,39 @@ const runLintPilot = ({ title, watch }: RunLintPilot) => {
program
.option('-e, --emoji <string>', 'customise the emoji displayed when running lint-pilot', '✈️')
.option('-t, --title <string>', 'customise the title displayed when running lint-pilot', 'Lint Pilot')

.option('-w, --watch', 'watch for file changes and re-run the linters', false)

.option('--ignore-dirs <directories...>', 'Directories to ignore globally')
.option('--ignore-patterns <patterns...>', 'File patterns to ignore globally')
.option('--eslint-include <patterns...>', 'File patterns to include for ESLint')

.option('--debug', 'output additional debug information including the list of files being linted', false)
.action(({ debug, emoji, title, watch }) => {
.action(({ debug, emoji, eslintInclude, ignoreDirs, ignorePatterns, title, watch }) => {
clearTerminal()
colourLog.title(`${emoji} ${title} ${emoji}`)
console.log()

global.debug = debug

runLintPilot({ title, watch })
const filePatterns = getFilePatterns({
eslintInclude,
ignoreDirs,
ignorePatterns,
})
runLintPilot({ filePatterns, title, watch })

if (watch) {
watchFiles({
filePatterns: [
'**/*.{cjs,js,jsx,mjs,ts,tsx}',
'**/*.{md,mdx}',
'**/*.{css,scss,less,sass,styl,stylus}',
],
ignorePatterns: [
'**/*.min.*',
'**/+(coverage|node_modules)/**',
],
filePatterns: Object.values(filePatterns.includePatterns).flat(),
ignorePatterns: filePatterns.ignorePatterns,
})

fileChangeEvent.on(Events.FILE_CHANGED, ({ message }) => {
clearTerminal()
colourLog.info(message)
console.log()
runLintPilot({ title, watch })
runLintPilot({ filePatterns, title, watch })
})
}
})
Expand Down
4 changes: 2 additions & 2 deletions src/sourceFiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import colourLog from '@Utils/colourLog'
import { pluralise } from '@Utils/transform'

interface SourceFiles {
filePattern: string
ignore: Array<string> | string
filePattern: Array<string>
ignore: Array<string>
linter: Linter
}

Expand Down
12 changes: 11 additions & 1 deletion src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,21 @@ interface LintReport {
* LINT PILOT
*/

interface FilePatterns {
includePatterns: {
[key in Linter]: Array<string>
}
ignorePatterns: Array<string>
}

interface RunLinter {
filePattern: string
filePattern: Array<string>
ignore: Array<string>
linter: Linter
}

interface RunLintPilot {
filePatterns: FilePatterns
title: string
watch: boolean
}
Expand All @@ -69,6 +78,7 @@ interface RunLintPilot {
*/

export type {
FilePatterns,
FormattedResult,
LintReport,
ReportResults,
Expand Down

0 comments on commit 2287653

Please sign in to comment.