1
0
mirror of https://github.com/sasjs/lint.git synced 2025-12-11 01:44:36 +00:00

feat: honour .gitignore and ignoreList from config when linting filesystem

This commit is contained in:
2022-08-12 15:49:28 +05:00
parent e1bcf5b06b
commit 40aea383b7
7 changed files with 6679 additions and 18 deletions

6548
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,7 @@
"prebuild": "node checkNodeVersion",
"prepublishOnly": "cp -r ./build/* . && rm -rf ./build && rm -rf ./src && rm tsconfig.json",
"postpublish": "git clean -fd",
"package:lib": "npm run build && cp ./package.json build && cp README.md build && cd build && npm version \"5.0.0\" && npm pack",
"package:lib": "npm run build && cp ./package.json ./checkNodeVersion.js build && cp README.md build && cd build && npm version \"5.0.0\" && npm pack",
"lint:fix": "npx prettier --write \"{src,test}/**/*.{ts,tsx,js,jsx,html,css,sass,less,json,yml,md,graphql}\"",
"lint": "npx prettier --check \"{src,test}/**/*.{ts,tsx,js,jsx,html,css,sass,less,json,yml,md,graphql}\"",
"prepare": "git rev-parse --git-dir && git config core.hooksPath ./.git-hooks || true"
@@ -48,6 +48,7 @@
"typescript": "^4.3.2"
},
"dependencies": {
"@sasjs/utils": "^2.19.0"
"@sasjs/utils": "^2.19.0",
"ignore": "^5.2.0"
}
}

View File

@@ -1,18 +1,20 @@
import { readFile } from '@sasjs/utils/file'
import { LintConfig } from '../types/LintConfig'
import { getLintConfig } from '../utils/getLintConfig'
import { Diagnostic, LintConfig } from '../types'
import { getLintConfig, isIgnored } from '../utils'
import { processFile, processText } from './shared'
/**
* Analyses and produces a set of diagnostics for the file at the given path.
* @param {string} filePath - the path to the file to be linted.
* @param {LintConfig} configuration - an optional configuration. When not passed in, this is read from the .sasjslint file.
* @returns {Diagnostic[]} array of diagnostic objects, each containing a warning, line number and column number.
* @returns {Promise<Diagnostic[]>} array of diagnostic objects, each containing a warning, line number and column number.
*/
export const lintFile = async (
filePath: string,
configuration?: LintConfig
) => {
): Promise<Diagnostic[]> => {
if (await isIgnored(filePath)) return []
const config = configuration || (await getLintConfig())
const text = await readFile(filePath)

View File

@@ -1,10 +1,7 @@
import { listSubFoldersInFolder } from '@sasjs/utils/file'
import path from 'path'
import { Diagnostic } from '../types/Diagnostic'
import { LintConfig } from '../types/LintConfig'
import { asyncForEach } from '../utils/asyncForEach'
import { getLintConfig } from '../utils/getLintConfig'
import { listSasFiles } from '../utils/listSasFiles'
import { Diagnostic, LintConfig } from '../types'
import { asyncForEach, getLintConfig, isIgnored, listSasFiles } from '../utils'
import { lintFile } from './lintFile'
const excludeFolders = [
@@ -28,6 +25,9 @@ export const lintFolder = async (
) => {
const config = configuration || (await getLintConfig())
let diagnostics: Map<string, Diagnostic[]> = new Map<string, Diagnostic[]>()
if (await isIgnored(folderPath)) return diagnostics
const fileNames = await listSasFiles(folderPath)
await asyncForEach(fileNames, async (fileName) => {
const filePath = path.join(folderPath, fileName)
@@ -39,10 +39,8 @@ export const lintFolder = async (
)
await asyncForEach(subFolders, async (subFolder) => {
const subFolderDiagnostics = await lintFolder(
path.join(folderPath, subFolder),
config
)
const subFolderPath = path.join(folderPath, subFolder)
const subFolderDiagnostics = await lintFolder(subFolderPath, config)
diagnostics = new Map([...diagnostics, ...subFolderDiagnostics])
})

View File

@@ -1,4 +1,6 @@
export * from './asyncForEach'
export * from './getLintConfig'
export * from './getProjectRoot'
export * from './isIgnored'
export * from './listSasFiles'
export * from './splitText'

View File

@@ -0,0 +1,83 @@
import * as fileModule from '@sasjs/utils/file'
import * as getProjectRootModule from './getProjectRoot'
import * as getLintConfigModule from './getLintConfig'
import { DefaultLintConfiguration } from './getLintConfig'
import { LintConfig } from '../types'
import { isIgnored } from './isIgnored'
describe('isIgnored', () => {
it('should return true if provided path matches the patterns from .gitignore', async () => {
jest
.spyOn(getLintConfigModule, 'getLintConfig')
.mockImplementationOnce(
async () => new LintConfig(DefaultLintConfiguration)
)
jest
.spyOn(fileModule, 'fileExists')
.mockImplementationOnce(async () => true)
jest
.spyOn(fileModule, 'readFile')
.mockImplementationOnce(async () => 'sasjs')
jest
.spyOn(getProjectRootModule, 'getProjectRoot')
.mockImplementationOnce(async () => '')
const ignored = await isIgnored('sasjs')
expect(ignored).toBeTruthy()
})
it('should return true if provided path matches any pattern from ignoreList (.sasjslint)', async () => {
jest
.spyOn(fileModule, 'fileExists')
.mockImplementationOnce(async () => false)
jest
.spyOn(getProjectRootModule, 'getProjectRoot')
.mockImplementationOnce(async () => '')
const ignored = await isIgnored(
'sasjs',
new LintConfig({
...DefaultLintConfiguration,
ignoreList: ['sasjs']
})
)
expect(ignored).toBeTruthy()
})
it('should return false if provided path does not matches any pattern from .gitignore and ignoreList (.sasjslint)', async () => {
jest
.spyOn(fileModule, 'fileExists')
.mockImplementationOnce(async () => true)
jest.spyOn(fileModule, 'readFile').mockImplementationOnce(async () => '')
jest
.spyOn(getProjectRootModule, 'getProjectRoot')
.mockImplementationOnce(async () => '')
const ignored = await isIgnored(
'sasjs',
new LintConfig(DefaultLintConfiguration)
)
expect(ignored).toBeFalsy()
})
it('should return false if provided path is equal to projectRoot', async () => {
jest
.spyOn(getProjectRootModule, 'getProjectRoot')
.mockImplementationOnce(async () => '')
const ignored = await isIgnored(
'',
new LintConfig(DefaultLintConfiguration)
)
expect(ignored).toBeFalsy()
})
})

33
src/utils/isIgnored.ts Normal file
View File

@@ -0,0 +1,33 @@
import { fileExists, readFile } from '@sasjs/utils'
import path from 'path'
import ignore from 'ignore'
import { getLintConfig, getProjectRoot } from '.'
import { LintConfig } from '../types'
/**
*
* @param fPath absolute path of file or folder
* @returns {Promise<boolean>} true if path matches the patterns from .gitignore file otherwise false
*/
export const isIgnored = async (
fPath: string,
configuration?: LintConfig
): Promise<boolean> => {
const config = configuration || (await getLintConfig())
const projectRoot = await getProjectRoot()
const gitIgnoreFilePath = path.join(projectRoot, '.gitignore')
const rootPath = projectRoot + path.sep
const relativePath = fPath.replace(rootPath, '')
if (fPath === projectRoot) return false
let gitIgnoreFileContent = ''
if (await fileExists(gitIgnoreFilePath))
gitIgnoreFileContent = await readFile(gitIgnoreFilePath)
return ignore()
.add(gitIgnoreFileContent)
.add(config.ignoreList)
.ignores(relativePath)
}