-
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
20 changed files
with
320 additions
and
68 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,6 @@ | ||
.vscode | ||
node_modules | ||
bin | ||
coverage | ||
coverage | ||
.rete-cli | ||
.sonar |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,3 +4,5 @@ node_modules | |
.github | ||
CODE_OF_CONDUCT.md | ||
CONTRIBUTING.md | ||
.rete-cli | ||
.sonar |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
|
||
export const SOURCE_FOLDER = 'src' | ||
export const TEST_FOLDER = 'test' | ||
export const RESULTS_FOLDER = '.rete-cli' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,10 @@ | ||
import { LintResult } from './results' | ||
import { LintResult, RuleMeta } from './results' | ||
|
||
export interface LinterResponse { | ||
rules: RuleMeta[] | ||
results: LintResult[] | ||
} | ||
|
||
export interface BaseLinter { | ||
run(): LintResult[] | Promise<LintResult[]> | ||
run(): LinterResponse | Promise<LinterResponse> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1,56 @@ | ||
import fs from 'fs' | ||
import { join } from 'path' | ||
|
||
import { SOURCE_FOLDER, TEST_FOLDER } from '../consts' | ||
import { RESULTS_FOLDER, SOURCE_FOLDER, TEST_FOLDER } from '../consts' | ||
import { ESLint } from './eslint' | ||
import { Formatter } from './formatter' | ||
import { LinterRunner } from './runner' | ||
import { toSonar } from './sonar' | ||
import { TypeCheck } from './type-check' | ||
import { TypeCoverage } from './type-coverage' | ||
|
||
export async function lint(fix?: boolean, quiet?: boolean) { | ||
export interface LintOptions { | ||
fix?: boolean | ||
quiet?: boolean | ||
output: ('stdout' | 'sonar')[] | ||
} | ||
|
||
// eslint-disable-next-line max-statements | ||
export async function lint(options: LintOptions) { | ||
const src = join(process.cwd(), SOURCE_FOLDER) | ||
const test = join(process.cwd(), TEST_FOLDER) | ||
|
||
if (options.output.length === 0) throw new Error('At least one output target must be specified') | ||
|
||
const runner = new LinterRunner() | ||
|
||
runner.addLinter(new ESLint({ targets: [src, test], fix })) | ||
runner.addLinter(new ESLint({ targets: [src, test], fix: options.fix })) | ||
runner.addLinter(new TypeCoverage({ src })) | ||
runner.addLinter(new TypeCheck({ config: 'tsconfig.json' })) | ||
|
||
const results = await runner.run() | ||
const errorResults = results.map(result => { | ||
return { | ||
...result, | ||
messages: result.messages.filter(message => message.severity === 2) | ||
} | ||
}) | ||
const formatter = new Formatter() | ||
const resultText = await formatter.format(quiet | ||
? errorResults | ||
: results) | ||
|
||
console.log(resultText) | ||
const { results, rules } = await runner.run() | ||
|
||
if (options.output.includes('sonar')) { | ||
const fileContent = JSON.stringify(toSonar(results, rules), null, 2) | ||
const filePath = join(process.cwd(), RESULTS_FOLDER, 'sonar.json') | ||
|
||
await fs.promises.mkdir(join(process.cwd(), RESULTS_FOLDER), { recursive: true }) | ||
await fs.promises.writeFile(filePath, fileContent) | ||
} | ||
|
||
if (options.output.includes('stdout')) { | ||
const errorResults = results.map(result => { | ||
return { | ||
...result, | ||
messages: result.messages.filter(message => message.severity === 2) | ||
} | ||
}) | ||
|
||
const formatter = new Formatter() | ||
const resultText = await formatter.format(options.quiet | ||
? errorResults | ||
: results) | ||
|
||
console.log(resultText) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import { LintMessage, LintResult, RuleMeta } from './results' | ||
|
||
interface Rule { | ||
id: string | ||
name: string | ||
description?: string | ||
engineId: string | ||
cleanCodeAttribute: 'FORMATTED' | 'CONVENTIONAL' | ||
impacts: { | ||
softwareQuality: 'MAINTAINABILITY' | 'RELIABILITY' | 'SECURITY' | ||
severity: 'HIGH' | 'MEDIUM' | 'LOW' | ||
}[] | ||
} | ||
|
||
interface Location { | ||
message: string | ||
filePath: string | ||
textRange: { | ||
startLine: number | ||
startColumn?: number | ||
endLine?: number | ||
endColumn?: number | ||
} | ||
} | ||
|
||
interface Issue { | ||
ruleId: string | ||
effortMinutes?: number | ||
primaryLocation: Location | ||
secondaryLocations?: Location[] | ||
} | ||
|
||
export interface Sonar { | ||
rules: Rule[] | ||
issues: Issue[] | ||
} | ||
|
||
interface MessageWithRuleId { | ||
filePath: string | ||
message: LintMessage & { ruleId: string } | ||
} | ||
|
||
export function toSonar(results: LintResult[], rules: RuleMeta[]): Sonar { | ||
const issues = results | ||
.flatMap(result => result.messages.map(message => ({ message, filePath: result.filePath }))) | ||
.filter((issue): issue is MessageWithRuleId => issue.message.ruleId !== null) | ||
|
||
return { | ||
issues: issues.map(issue => { | ||
const { filePath, message } = issue | ||
|
||
return { | ||
ruleId: message.ruleId, | ||
primaryLocation: { | ||
message: message.message, | ||
filePath, | ||
textRange: { | ||
startLine: message.line, | ||
startColumn: message.column - 1, | ||
endLine: message.endLine, | ||
endColumn: message.endColumn === undefined | ||
? undefined | ||
: message.endColumn - 1 | ||
} | ||
} | ||
} satisfies Issue | ||
}), | ||
rules: rules.map(rule => { | ||
return { | ||
id: rule.id, | ||
name: rule.id, | ||
description: rule.description, | ||
engineId: 'rete-cli', | ||
cleanCodeAttribute: 'FORMATTED', | ||
impacts: [{ | ||
softwareQuality: 'MAINTAINABILITY', | ||
severity: rule.severity === 2 | ||
? 'HIGH' | ||
: 'MEDIUM' | ||
}] | ||
} satisfies Rule | ||
}) | ||
} | ||
} |
Oops, something went wrong.