mirror of
https://github.com/sasjs/lint.git
synced 2025-12-10 17:34:36 +00:00
Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5ce33ab66c | ||
| 5290339c9e | |||
| 4772aa70c6 | |||
| 623d4df79d | |||
| 40aea383b7 | |||
| e1bcf5b06b | |||
|
|
51c6dd7c1a | ||
|
|
6e0f1c4167 | ||
|
|
5f905c88d9 | ||
|
|
ac95546910 | ||
|
|
7a00cc5f2d | ||
|
|
8950c97f84 | ||
|
|
49b124e5b8 | ||
|
|
1b15938477 | ||
|
|
f6fa20af1c | ||
|
|
cf5a0700f2 | ||
|
|
0dca988438 | ||
|
|
00dafa5bc0 | ||
|
|
39bffd39a4 | ||
|
|
ec95a798b7 | ||
|
|
acfc559f25 | ||
|
|
d204b5bac6 | ||
|
|
5602063879 | ||
|
|
31cee0af91 | ||
|
|
cd91780cf5 | ||
|
|
108bbfbaa5 | ||
|
|
f2edf1176a | ||
|
|
b5d446adc9 | ||
|
|
cc221bccc3 | ||
|
|
f38bcec582 | ||
|
|
75ab01cccf |
113
.all-contributorsrc
Normal file
113
.all-contributorsrc
Normal file
@@ -0,0 +1,113 @@
|
||||
{
|
||||
"files": [
|
||||
"README.md"
|
||||
],
|
||||
"imageSize": 100,
|
||||
"commit": false,
|
||||
"contributors": [
|
||||
{
|
||||
"login": "Carus11",
|
||||
"name": "Carus Kyle",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/4925828?v=4",
|
||||
"profile": "https://github.com/Carus11",
|
||||
"contributions": [
|
||||
"ideas"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "allanbowe",
|
||||
"name": "Allan Bowe",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/4420615?v=4",
|
||||
"profile": "https://github.com/allanbowe",
|
||||
"contributions": [
|
||||
"code",
|
||||
"test",
|
||||
"review",
|
||||
"video",
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "YuryShkoda",
|
||||
"name": "Yury Shkoda",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/25773492?v=4",
|
||||
"profile": "https://www.erudicat.com/",
|
||||
"contributions": [
|
||||
"code",
|
||||
"test",
|
||||
"projectManagement",
|
||||
"video",
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "krishna-acondy",
|
||||
"name": "Krishna Acondy",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/2980428?v=4",
|
||||
"profile": "https://krishna-acondy.io/",
|
||||
"contributions": [
|
||||
"code",
|
||||
"test",
|
||||
"review",
|
||||
"infra",
|
||||
"platform",
|
||||
"maintenance",
|
||||
"content"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "saadjutt01",
|
||||
"name": "Muhammad Saad ",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/8914650?v=4",
|
||||
"profile": "https://github.com/saadjutt01",
|
||||
"contributions": [
|
||||
"code",
|
||||
"test",
|
||||
"review",
|
||||
"mentoring",
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "sabhas",
|
||||
"name": "Sabir Hassan",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/82647447?v=4",
|
||||
"profile": "https://github.com/sabhas",
|
||||
"contributions": [
|
||||
"code",
|
||||
"test",
|
||||
"review",
|
||||
"ideas"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "medjedovicm",
|
||||
"name": "Mihajlo Medjedovic",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/18329105?v=4",
|
||||
"profile": "https://github.com/medjedovicm",
|
||||
"contributions": [
|
||||
"code",
|
||||
"test",
|
||||
"review",
|
||||
"infra"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "VladislavParhomchik",
|
||||
"name": "Vladislav Parhomchik",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/83717836?v=4",
|
||||
"profile": "https://github.com/VladislavParhomchik",
|
||||
"contributions": [
|
||||
"test",
|
||||
"review"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contributorsPerLine": 7,
|
||||
"projectName": "lint",
|
||||
"projectOwner": "sasjs",
|
||||
"repoType": "github",
|
||||
"repoHost": "https://github.com",
|
||||
"skipCi": true,
|
||||
"commitConvention": "none"
|
||||
}
|
||||
10
.github/dependabot.yml
vendored
10
.github/dependabot.yml
vendored
@@ -1,7 +1,7 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: npm
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: daily
|
||||
open-pull-requests-limit: 10
|
||||
- package-ecosystem: npm
|
||||
directory: '/'
|
||||
schedule:
|
||||
interval: monthly
|
||||
open-pull-requests-limit: 10
|
||||
|
||||
5
.github/workflows/build.yml
vendored
5
.github/workflows/build.yml
vendored
@@ -13,14 +13,15 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [12.x]
|
||||
node-version: [lts/*]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: npm
|
||||
- name: Install Dependencies
|
||||
run: npm ci
|
||||
- name: Check Code Style
|
||||
|
||||
54
CONTRIBUTING.md
Normal file
54
CONTRIBUTING.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# Contributing
|
||||
|
||||
Contributions to `@sasjs/lint` are very welcome!
|
||||
Please fill in the pull request template and make sure that your code changes are adequately covered with tests when making a PR.
|
||||
|
||||
## Architecture
|
||||
|
||||
This project implements a number of rules for SAS projects and code. There are three types of rules:
|
||||
|
||||
* File rules - rules applied at the file level
|
||||
* Line rules - rules applied to each line of a file
|
||||
* Path rules - rules applied to paths and file names
|
||||
|
||||
When implementing a new rule, place it in the appropriate folder for its type.
|
||||
Please also make sure to export it from the `index.ts` file in that folder.
|
||||
|
||||
The file for each rule typically exports an object that conforms to the `LintRule` interface.
|
||||
This means it will have a `type`, `name`, `description` and `message` at a minimum.
|
||||
|
||||
File, line and path lint rules also have a `test` property.
|
||||
This is a function that will run a piece of logic against the supplied item and produce an array of `Diagnostic` objects.
|
||||
These objects can be used in the consuming application to display the problems in the code.
|
||||
|
||||
With some lint rules, we can also write logic that can automatically fix the issues found.
|
||||
These rules will also have a `fix` property, which is a function that takes the original content -
|
||||
either a line or the entire contents of a file, and returns the transformed content with the fix applied.
|
||||
|
||||
## Testing
|
||||
|
||||
Testing is one of the most important steps when developing a new lint rule.
|
||||
It helps us ensure that our lint rules do what they are intended to do.
|
||||
|
||||
We use `jest` for testing, and since most of the code is based on pure functions, there is little mocking to do.
|
||||
This makes `@sasjs/lint` very easy to unit test, and so there is no excuse for not testing a new rule. :)
|
||||
|
||||
When adding a new rule, please make sure that all positive and negative scenarios are tested in separate test cases.
|
||||
When modifying an existing rule, ensure that your changes haven't affected existing functionality by running the tests on your machine.
|
||||
|
||||
You can run the tests using `npm test`.
|
||||
|
||||
## Code Style
|
||||
|
||||
This repository uses `Prettier` to ensure a uniform code style.
|
||||
If you are using VS Code for development, you can automatically fix your code to match the style as follows:
|
||||
|
||||
- Install the `Prettier` extension for VS Code.
|
||||
- Open your `settings.json` file by choosing 'Preferences: Open Settings (JSON)' from the command palette.
|
||||
- Add the following items to the JSON.
|
||||
```
|
||||
"editor.formatOnSave": true,
|
||||
"editor.formatOnPaste": true,
|
||||
```
|
||||
|
||||
If you are using another editor, or are unable to install the extension, you can run `npm run lint:fix` to fix the formatting after you've made your changes.
|
||||
38
README.md
38
README.md
@@ -1,4 +1,9 @@
|
||||
[](https://dependabot.com)
|
||||
[](/LICENSE)
|
||||

|
||||
[](https://github.com/sasjs/lint/issues?q=is%3Aissue+is%3Aclosed)
|
||||
[](https://github.com/sasjs/lint/issues)
|
||||

|
||||
[](https://gitpod.io/#https://github.com/sasjs/lint)
|
||||
|
||||
# SAS Code linting and formatting
|
||||
|
||||
@@ -145,3 +150,34 @@ The SAS 9 Health Check is a 'plug & play' product, that uses the [SAS 9 REST API
|
||||
Contact [Allan Bowe](https://www.linkedin.com/in/allanbowe/) for further details.
|
||||
|
||||
|
||||
|
||||
## Contributors ✨
|
||||
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
||||
[](#contributors-)
|
||||
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
||||
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
|
||||
|
||||
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
||||
<!-- prettier-ignore-start -->
|
||||
<!-- markdownlint-disable -->
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/Carus11"><img src="https://avatars.githubusercontent.com/u/4925828?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Carus Kyle</b></sub></a><br /><a href="#ideas-Carus11" title="Ideas, Planning, & Feedback">🤔</a></td>
|
||||
<td align="center"><a href="https://github.com/allanbowe"><img src="https://avatars.githubusercontent.com/u/4420615?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Allan Bowe</b></sub></a><br /><a href="https://github.com/sasjs/lint/commits?author=allanbowe" title="Code">💻</a> <a href="https://github.com/sasjs/lint/commits?author=allanbowe" title="Tests">⚠️</a> <a href="https://github.com/sasjs/lint/pulls?q=is%3Apr+reviewed-by%3Aallanbowe" title="Reviewed Pull Requests">👀</a> <a href="#video-allanbowe" title="Videos">📹</a> <a href="https://github.com/sasjs/lint/commits?author=allanbowe" title="Documentation">📖</a></td>
|
||||
<td align="center"><a href="https://www.erudicat.com/"><img src="https://avatars.githubusercontent.com/u/25773492?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Yury Shkoda</b></sub></a><br /><a href="https://github.com/sasjs/lint/commits?author=YuryShkoda" title="Code">💻</a> <a href="https://github.com/sasjs/lint/commits?author=YuryShkoda" title="Tests">⚠️</a> <a href="#projectManagement-YuryShkoda" title="Project Management">📆</a> <a href="#video-YuryShkoda" title="Videos">📹</a> <a href="https://github.com/sasjs/lint/commits?author=YuryShkoda" title="Documentation">📖</a></td>
|
||||
<td align="center"><a href="https://krishna-acondy.io/"><img src="https://avatars.githubusercontent.com/u/2980428?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Krishna Acondy</b></sub></a><br /><a href="https://github.com/sasjs/lint/commits?author=krishna-acondy" title="Code">💻</a> <a href="https://github.com/sasjs/lint/commits?author=krishna-acondy" title="Tests">⚠️</a> <a href="https://github.com/sasjs/lint/pulls?q=is%3Apr+reviewed-by%3Akrishna-acondy" title="Reviewed Pull Requests">👀</a> <a href="#infra-krishna-acondy" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#platform-krishna-acondy" title="Packaging/porting to new platform">📦</a> <a href="#maintenance-krishna-acondy" title="Maintenance">🚧</a> <a href="#content-krishna-acondy" title="Content">🖋</a></td>
|
||||
<td align="center"><a href="https://github.com/saadjutt01"><img src="https://avatars.githubusercontent.com/u/8914650?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Muhammad Saad </b></sub></a><br /><a href="https://github.com/sasjs/lint/commits?author=saadjutt01" title="Code">💻</a> <a href="https://github.com/sasjs/lint/commits?author=saadjutt01" title="Tests">⚠️</a> <a href="https://github.com/sasjs/lint/pulls?q=is%3Apr+reviewed-by%3Asaadjutt01" title="Reviewed Pull Requests">👀</a> <a href="#mentoring-saadjutt01" title="Mentoring">🧑🏫</a> <a href="https://github.com/sasjs/lint/commits?author=saadjutt01" title="Documentation">📖</a></td>
|
||||
<td align="center"><a href="https://github.com/sabhas"><img src="https://avatars.githubusercontent.com/u/82647447?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Sabir Hassan</b></sub></a><br /><a href="https://github.com/sasjs/lint/commits?author=sabhas" title="Code">💻</a> <a href="https://github.com/sasjs/lint/commits?author=sabhas" title="Tests">⚠️</a> <a href="https://github.com/sasjs/lint/pulls?q=is%3Apr+reviewed-by%3Asabhas" title="Reviewed Pull Requests">👀</a> <a href="#ideas-sabhas" title="Ideas, Planning, & Feedback">🤔</a></td>
|
||||
<td align="center"><a href="https://github.com/medjedovicm"><img src="https://avatars.githubusercontent.com/u/18329105?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mihajlo Medjedovic</b></sub></a><br /><a href="https://github.com/sasjs/lint/commits?author=medjedovicm" title="Code">💻</a> <a href="https://github.com/sasjs/lint/commits?author=medjedovicm" title="Tests">⚠️</a> <a href="https://github.com/sasjs/lint/pulls?q=is%3Apr+reviewed-by%3Amedjedovicm" title="Reviewed Pull Requests">👀</a> <a href="#infra-medjedovicm" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/VladislavParhomchik"><img src="https://avatars.githubusercontent.com/u/83717836?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Vladislav Parhomchik</b></sub></a><br /><a href="https://github.com/sasjs/lint/commits?author=VladislavParhomchik" title="Tests">⚠️</a> <a href="https://github.com/sasjs/lint/pulls?q=is%3Apr+reviewed-by%3AVladislavParhomchik" title="Reviewed Pull Requests">👀</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- markdownlint-restore -->
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||
|
||||
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
|
||||
|
||||
16
checkNodeVersion.js
Normal file
16
checkNodeVersion.js
Normal file
@@ -0,0 +1,16 @@
|
||||
const result = process.versions
|
||||
if (result && result.node) {
|
||||
if (parseInt(result.node) < 14) {
|
||||
console.log(
|
||||
'\x1b[31m%s\x1b[0m',
|
||||
`❌ Process failed due to Node Version,\nPlease install and use Node Version >= 14\nYour current Node Version is: ${result.node}`
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
} else {
|
||||
console.log(
|
||||
'\x1b[31m%s\x1b[0m',
|
||||
'Something went wrong while checking Node version'
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
6935
package-lock.json
generated
6935
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
12
package.json
12
package.json
@@ -4,11 +4,13 @@
|
||||
"scripts": {
|
||||
"test": "jest --coverage",
|
||||
"build": "rimraf build && tsc",
|
||||
"preinstall": "node checkNodeVersion",
|
||||
"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",
|
||||
"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}'",
|
||||
"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"
|
||||
},
|
||||
"publishConfig": {
|
||||
@@ -39,12 +41,14 @@
|
||||
"devDependencies": {
|
||||
"@types/jest": "^26.0.23",
|
||||
"@types/node": "^15.12.2",
|
||||
"all-contributors-cli": "^6.20.0",
|
||||
"jest": "^26.6.3",
|
||||
"rimraf": "^3.0.2",
|
||||
"ts-jest": "^26.5.6",
|
||||
"typescript": "^4.3.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@sasjs/utils": "^2.19.0"
|
||||
"@sasjs/utils": "^2.19.0",
|
||||
"ignore": "^5.2.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,6 +140,14 @@
|
||||
"description": "Enforces Macro Definition syntax. Shows a warning when incorrect syntax is used.",
|
||||
"default": true,
|
||||
"examples": [true, false]
|
||||
},
|
||||
"ignoreList": {
|
||||
"$id": "#/properties/ignoreList",
|
||||
"type": "object",
|
||||
"title": "ignoreList",
|
||||
"description": "An array of paths or path patterns to ignore matching resources from linting. Files or folders matching patterns in .gitignore will always be ignored.",
|
||||
"default": ["sasjsbuild/", "sasjsresults/"],
|
||||
"examples": ["sasjs/services", "appinit.sas"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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])
|
||||
})
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import { FileLintRule, LineLintRule, PathLintRule } from './LintRule'
|
||||
* More types of rules, when available, will be added here.
|
||||
*/
|
||||
export class LintConfig {
|
||||
readonly ignoreList: string[] = []
|
||||
readonly lineLintRules: LineLintRule[] = []
|
||||
readonly fileLintRules: FileLintRule[] = []
|
||||
readonly pathLintRules: PathLintRule[] = []
|
||||
@@ -33,6 +34,20 @@ export class LintConfig {
|
||||
readonly lineEndings: LineEndings = LineEndings.LF
|
||||
|
||||
constructor(json?: any) {
|
||||
if (json?.ignoreList) {
|
||||
if (Array.isArray(json.ignoreList)) {
|
||||
json.ignoreList.forEach((item: any) => {
|
||||
if (typeof item === 'string') this.ignoreList.push(item)
|
||||
else
|
||||
throw new Error(
|
||||
`Property "ignoreList" has invalid type of values. It can contain only strings.`
|
||||
)
|
||||
})
|
||||
} else {
|
||||
throw new Error(`Property "ignoreList" can only be an array of strings`)
|
||||
}
|
||||
}
|
||||
|
||||
if (json?.noTrailingSpaces) {
|
||||
this.lineLintRules.push(noTrailingSpaces)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
export * from './asyncForEach'
|
||||
export * from './getLintConfig'
|
||||
export * from './getProjectRoot'
|
||||
export * from './isIgnored'
|
||||
export * from './listSasFiles'
|
||||
export * from './splitText'
|
||||
|
||||
119
src/utils/isIgnored.spec.ts
Normal file
119
src/utils/isIgnored.spec.ts
Normal file
@@ -0,0 +1,119 @@
|
||||
import path from 'path'
|
||||
import * as fileModule from '@sasjs/utils/file'
|
||||
import * as getLintConfigModule from './getLintConfig'
|
||||
import { getProjectRoot, DefaultLintConfiguration, isIgnored } from '.'
|
||||
import { LintConfig } from '../types'
|
||||
|
||||
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')
|
||||
|
||||
const projectRoot = await getProjectRoot()
|
||||
const pathToTest = path.join(projectRoot, 'sasjs')
|
||||
|
||||
const ignored = await isIgnored(pathToTest)
|
||||
|
||||
expect(ignored).toBeTruthy()
|
||||
})
|
||||
|
||||
it('should return true if top level path of provided path is in .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/common')
|
||||
|
||||
const projectRoot = await getProjectRoot()
|
||||
const pathToTest = path.join(projectRoot, 'sasjs/common/init/init.sas')
|
||||
|
||||
const ignored = await isIgnored(pathToTest)
|
||||
|
||||
expect(ignored).toBeTruthy()
|
||||
})
|
||||
|
||||
it('should return true if provided path matches any pattern from ignoreList (.sasjslint)', async () => {
|
||||
jest
|
||||
.spyOn(fileModule, 'fileExists')
|
||||
.mockImplementationOnce(async () => false)
|
||||
|
||||
const projectRoot = await getProjectRoot()
|
||||
const pathToTest = path.join(projectRoot, 'sasjs')
|
||||
|
||||
const ignored = await isIgnored(
|
||||
pathToTest,
|
||||
new LintConfig({
|
||||
...DefaultLintConfiguration,
|
||||
ignoreList: ['sasjs']
|
||||
})
|
||||
)
|
||||
|
||||
expect(ignored).toBeTruthy()
|
||||
})
|
||||
|
||||
it('should return true if top level path of provided path is in ignoreList (.sasjslint)', async () => {
|
||||
jest
|
||||
.spyOn(fileModule, 'fileExists')
|
||||
.mockImplementationOnce(async () => false)
|
||||
|
||||
const projectRoot = await getProjectRoot()
|
||||
const pathToTest = path.join(projectRoot, 'sasjs/common/init/init.sas')
|
||||
|
||||
const ignored = await isIgnored(
|
||||
pathToTest,
|
||||
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 () => '')
|
||||
|
||||
const projectRoot = await getProjectRoot()
|
||||
const pathToTest = path.join(projectRoot, 'sasjs')
|
||||
|
||||
const ignored = await isIgnored(
|
||||
pathToTest,
|
||||
new LintConfig(DefaultLintConfiguration)
|
||||
)
|
||||
|
||||
expect(ignored).toBeFalsy()
|
||||
})
|
||||
|
||||
it('should return false if provided path is equal to projectRoot', async () => {
|
||||
const projectRoot = await getProjectRoot()
|
||||
const pathToTest = path.join(projectRoot, '')
|
||||
|
||||
const ignored = await isIgnored(
|
||||
pathToTest,
|
||||
new LintConfig(DefaultLintConfiguration)
|
||||
)
|
||||
|
||||
expect(ignored).toBeFalsy()
|
||||
})
|
||||
})
|
||||
34
src/utils/isIgnored.ts
Normal file
34
src/utils/isIgnored.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { fileExists, readFile } from '@sasjs/utils'
|
||||
import path from 'path'
|
||||
import ignore from 'ignore'
|
||||
import { getLintConfig, getProjectRoot } from '.'
|
||||
import { LintConfig } from '../types'
|
||||
|
||||
/**
|
||||
* A function to check if file/folder path matches any pattern from .gitignore or ignoreList (.sasjsLint)
|
||||
*
|
||||
* @param {string} 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)
|
||||
}
|
||||
Reference in New Issue
Block a user