fix: usage of __dirname, lint rules and corresponding fixes
This commit is contained in:
parent
052ca736d2
commit
3b7e48a494
|
@ -15,8 +15,7 @@
|
||||||
"eslint-plugin-mocha",
|
"eslint-plugin-mocha",
|
||||||
"eslint-plugin-no-null",
|
"eslint-plugin-no-null",
|
||||||
"eslint-plugin-sonarjs",
|
"eslint-plugin-sonarjs",
|
||||||
"@typescript-eslint",
|
"@typescript-eslint"
|
||||||
"@typescript-eslint/tslint"
|
|
||||||
],
|
],
|
||||||
"rules": {
|
"rules": {
|
||||||
"@typescript-eslint/adjacent-overload-signatures": "error",
|
"@typescript-eslint/adjacent-overload-signatures": "error",
|
||||||
|
@ -291,72 +290,6 @@
|
||||||
"sonarjs/no-redundant-jump": "error",
|
"sonarjs/no-redundant-jump": "error",
|
||||||
"sonarjs/no-same-line-conditional": "error",
|
"sonarjs/no-same-line-conditional": "error",
|
||||||
"sonarjs/no-useless-catch": "error",
|
"sonarjs/no-useless-catch": "error",
|
||||||
"sonarjs/prefer-immediate-return": "error",
|
"sonarjs/prefer-immediate-return": "error"
|
||||||
"@typescript-eslint/tslint/config": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
"rules": {
|
|
||||||
"ban": [
|
|
||||||
true,
|
|
||||||
{
|
|
||||||
"message": "use lodash isString",
|
|
||||||
"name": [
|
|
||||||
"util",
|
|
||||||
"isString"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"message": "use lodash isNil",
|
|
||||||
"name": [
|
|
||||||
"util",
|
|
||||||
"isNullOrUndefined"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"import-spacing": true,
|
|
||||||
"jsdoc-format": [
|
|
||||||
true,
|
|
||||||
"check-multiline-start"
|
|
||||||
],
|
|
||||||
"no-dynamic-delete": true,
|
|
||||||
"no-inferred-empty-object-type": true,
|
|
||||||
"no-reference-import": true,
|
|
||||||
"object-literal-sort-keys": true,
|
|
||||||
"one-line": [
|
|
||||||
true,
|
|
||||||
"check-catch",
|
|
||||||
"check-else",
|
|
||||||
"check-finally",
|
|
||||||
"check-open-brace",
|
|
||||||
"check-whitespace"
|
|
||||||
],
|
|
||||||
"prefer-switch": true,
|
|
||||||
"strict-type-predicates": true,
|
|
||||||
"trailing-comma": [
|
|
||||||
true,
|
|
||||||
{
|
|
||||||
"esSpecCompliant": true,
|
|
||||||
"multiline": {
|
|
||||||
"arrays": "always",
|
|
||||||
"functions": "never",
|
|
||||||
"object": "always"
|
|
||||||
},
|
|
||||||
"singleline": "never"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"whitespace": [
|
|
||||||
true,
|
|
||||||
"check-branch",
|
|
||||||
"check-decl",
|
|
||||||
"check-operator",
|
|
||||||
"check-separator",
|
|
||||||
"check-type",
|
|
||||||
"check-typecast",
|
|
||||||
"check-type-operator",
|
|
||||||
"check-rest-spread"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
"es2017",
|
"es2017",
|
||||||
"esnext.asynciterable"
|
"esnext.asynciterable"
|
||||||
],
|
],
|
||||||
"module": "es6",
|
"module": "esnext",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"noImplicitAny": true,
|
"noImplicitAny": true,
|
||||||
"noImplicitReturns": true,
|
"noImplicitReturns": true,
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { createLogger } from 'bunyan';
|
import { createLogger } from 'bunyan';
|
||||||
import yargs from 'yargs';
|
import yargs from 'yargs';
|
||||||
const { showCompletionScript } = yargs;
|
|
||||||
|
|
||||||
import { loadConfig } from './config/index.js';
|
import { loadConfig } from './config/index.js';
|
||||||
import { CONFIG_ARGS_NAME, CONFIG_ARGS_PATH, MODE, parseArgs } from './config/args.js';
|
import { CONFIG_ARGS_NAME, CONFIG_ARGS_PATH, MODE, parseArgs } from './config/args.js';
|
||||||
|
@ -19,7 +18,7 @@ export const STATUS_MAX = 255;
|
||||||
export async function main(argv: Array<string>): Promise<number> {
|
export async function main(argv: Array<string>): Promise<number> {
|
||||||
const { args, mode } = await parseArgs(argv.slice(ARGS_START));
|
const { args, mode } = await parseArgs(argv.slice(ARGS_START));
|
||||||
if (mode === MODE.complete) {
|
if (mode === MODE.complete) {
|
||||||
showCompletionScript();
|
yargs(argv).showCompletionScript();
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import yargs, { Options } from 'yargs';
|
import yargs, { Options } from 'yargs';
|
||||||
const { usage } = yargs;
|
|
||||||
|
|
||||||
import { RuleSelector, RuleSources } from '../rule/index.js';
|
import { RuleSelector, RuleSources } from '../rule/index.js';
|
||||||
import { VERSION_INFO } from '../version.js';
|
import { VERSION_INFO } from '../version.js';
|
||||||
|
@ -11,8 +10,6 @@ export enum MODE {
|
||||||
list = 'list',
|
list = 'list',
|
||||||
}
|
}
|
||||||
|
|
||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
||||||
|
|
||||||
export const CONFIG_ARGS_NAME = 'config-name';
|
export const CONFIG_ARGS_NAME = 'config-name';
|
||||||
export const CONFIG_ARGS_PATH = 'config-path';
|
export const CONFIG_ARGS_PATH = 'config-path';
|
||||||
|
|
||||||
|
@ -23,6 +20,7 @@ const RULE_OPTION: Options = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface Args {
|
export interface Args {
|
||||||
|
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
||||||
args: any;
|
args: any;
|
||||||
mode: string;
|
mode: string;
|
||||||
}
|
}
|
||||||
|
@ -50,15 +48,16 @@ export interface ParseResults {
|
||||||
export async function parseArgs(argv: Array<string>): Promise<ParseResults> {
|
export async function parseArgs(argv: Array<string>): Promise<ParseResults> {
|
||||||
let mode: MODE = MODE.check;
|
let mode: MODE = MODE.check;
|
||||||
|
|
||||||
const parser = usage('Usage: salty-dog <mode> [options]')
|
const parser = yargs(argv).usage('Usage: salty-dog <mode> [options]')
|
||||||
.command({
|
.command({
|
||||||
command: ['check', '*'],
|
command: ['check', '*'],
|
||||||
describe: 'validate the source documents',
|
describe: 'validate the source documents',
|
||||||
handler: (argi: any) => {
|
handler: (argi: unknown) => {
|
||||||
mode = MODE.check;
|
mode = MODE.check;
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.command({
|
.command({
|
||||||
|
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
||||||
builder: (cmd: any) => cmd.options({
|
builder: (cmd: any) => cmd.options({
|
||||||
coerce: {
|
coerce: {
|
||||||
default: false,
|
default: false,
|
||||||
|
@ -75,21 +74,21 @@ export async function parseArgs(argv: Array<string>): Promise<ParseResults> {
|
||||||
}),
|
}),
|
||||||
command: ['fix'],
|
command: ['fix'],
|
||||||
describe: 'validate the source document and insert defaults',
|
describe: 'validate the source document and insert defaults',
|
||||||
handler: (argi: any) => {
|
handler: (argi: unknown) => {
|
||||||
mode = MODE.fix;
|
mode = MODE.fix;
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.command({
|
.command({
|
||||||
command: ['list'],
|
command: ['list'],
|
||||||
describe: 'list active rules',
|
describe: 'list active rules',
|
||||||
handler: (argi: any) => {
|
handler: (argi: unknown) => {
|
||||||
mode = MODE.list;
|
mode = MODE.list;
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.command({
|
.command({
|
||||||
command: ['complete'],
|
command: ['complete'],
|
||||||
describe: 'generate tab completion script for bash or zsh',
|
describe: 'generate tab completion script for bash or zsh',
|
||||||
handler: (argi: any) => {
|
handler: (argi: unknown) => {
|
||||||
mode = MODE.complete;
|
mode = MODE.complete;
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -165,6 +164,7 @@ export async function parseArgs(argv: Array<string>): Promise<ParseResults> {
|
||||||
.alias('version', 'v');
|
.alias('version', 'v');
|
||||||
|
|
||||||
// @TODO: this should not need a cast but the parser's type omits command options and doesn't expose camelCase
|
// @TODO: this should not need a cast but the parser's type omits command options and doesn't expose camelCase
|
||||||
|
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
||||||
const args = parser.parse(argv) as any;
|
const args = parser.parse(argv) as any;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import { doesExist, NotFoundError } from '@apextoaster/js-utils';
|
import { doesExist, NotFoundError } from '@apextoaster/js-utils';
|
||||||
import { Stream } from 'bunyan';
|
import { Stream } from 'bunyan';
|
||||||
import { LogLevel } from 'noicejs';
|
import { LogLevel } from 'noicejs';
|
||||||
import { join } from 'path';
|
import { dirname, join } from 'path';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
|
||||||
import { YamlParser } from '../parser/YamlParser.js';
|
import { YamlParser } from '../parser/YamlParser.js';
|
||||||
import { readSource } from '../source.js';
|
import { readSource } from '../source.js';
|
||||||
|
@ -18,6 +19,10 @@ export interface ConfigData {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function dirName(): string {
|
||||||
|
return dirname(fileURLToPath(import.meta.url));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* With the given name, generate all potential config paths in their complete, absolute form.
|
* With the given name, generate all potential config paths in their complete, absolute form.
|
||||||
*
|
*
|
||||||
|
@ -37,8 +42,9 @@ export function completePaths(name: string, extras: Array<string>): Array<string
|
||||||
paths.push(join(home, name));
|
paths.push(join(home, name));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (__dirname !== '') {
|
const cwd = dirName();
|
||||||
paths.push(join(__dirname, name));
|
if (cwd !== '') {
|
||||||
|
paths.push(join(cwd, name));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const e of extras) {
|
for (const e of extras) {
|
||||||
|
@ -56,7 +62,9 @@ export async function loadConfig(name: string, ...extras: Array<string>): Promis
|
||||||
if (doesExist(data)) {
|
if (doesExist(data)) {
|
||||||
const parser = new YamlParser();
|
const parser = new YamlParser();
|
||||||
const [head] = parser.parse(data);
|
const [head] = parser.parse(data);
|
||||||
return head;
|
|
||||||
|
/* eslint-disable-next-line sonarjs/prefer-immediate-return */
|
||||||
|
return head as any; // TODO: validate config
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { VERSION_INFO } from './version.js';
|
import { VERSION_INFO } from './version.js';
|
||||||
|
|
||||||
export default {
|
export {
|
||||||
VERSION_INFO,
|
VERSION_INFO,
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,8 +26,8 @@ export class YamlParser implements Parser {
|
||||||
include.setSchema(this.schema);
|
include.setSchema(this.schema);
|
||||||
}
|
}
|
||||||
|
|
||||||
public dump(...data: Array<any>): string {
|
public dump(...data: Array<unknown>): string {
|
||||||
const docs: Array<any> = [];
|
const docs: Array<unknown> = [];
|
||||||
for (const doc of data) {
|
for (const doc of data) {
|
||||||
const part = dump(doc, {
|
const part = dump(doc, {
|
||||||
schema: this.schema,
|
schema: this.schema,
|
||||||
|
@ -37,9 +37,9 @@ export class YamlParser implements Parser {
|
||||||
return docs.join('\n---\n\n');
|
return docs.join('\n---\n\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
public parse(body: string): Array<any> {
|
public parse(body: string): Array<unknown> {
|
||||||
const docs: Array<any> = [];
|
const docs: Array<unknown> = [];
|
||||||
loadAll(body, (doc: any) => docs.push(doc), {
|
loadAll(body, (doc: unknown) => docs.push(doc), {
|
||||||
schema: this.schema,
|
schema: this.schema,
|
||||||
});
|
});
|
||||||
return docs;
|
return docs;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
export interface Parser {
|
export interface Parser {
|
||||||
dump(...data: Array<any>): string;
|
dump(...data: Array<unknown>): string;
|
||||||
parse(body: string): Array<any>;
|
parse(body: string): Array<unknown>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import { doesExist, hasItems } from '@apextoaster/js-utils';
|
import { doesExist, hasItems } from '@apextoaster/js-utils';
|
||||||
import { ErrorObject, ValidateFunction } from 'ajv';
|
import { ErrorObject, ValidateFunction } from 'ajv';
|
||||||
|
import lodash from 'lodash';
|
||||||
import { LogLevel } from 'noicejs';
|
import { LogLevel } from 'noicejs';
|
||||||
|
|
||||||
import { Rule, RuleData } from './index.js';
|
|
||||||
import { Visitor, VisitorError, VisitorResult } from '../visitor/index.js';
|
import { Visitor, VisitorError, VisitorResult } from '../visitor/index.js';
|
||||||
import { VisitorContext } from '../visitor/VisitorContext.js';
|
import { VisitorContext } from '../visitor/VisitorContext.js';
|
||||||
|
import { Rule, RuleData } from './index.js';
|
||||||
|
|
||||||
import lodash from 'lodash';
|
|
||||||
const { cloneDeep, defaultTo } = lodash;
|
const { cloneDeep, defaultTo } = lodash;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -162,13 +162,23 @@ export async function loadRulePaths(paths: Array<string>, ctx: VisitorContext):
|
||||||
return rules;
|
return rules;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function loadRuleModules(modules: Array<string>, ctx: VisitorContext, r = require): Promise<Array<Rule>> {
|
type LoadBack = (path: string) => Promise<unknown>;
|
||||||
|
|
||||||
|
export async function loadRuleModules(modules: Array<string>, ctx: VisitorContext, load?: LoadBack): Promise<Array<Rule>> {
|
||||||
const rules = [];
|
const rules = [];
|
||||||
|
|
||||||
|
function loadModule(path: string) {
|
||||||
|
if (doesExist(load)) {
|
||||||
|
return load(path);
|
||||||
|
} else {
|
||||||
|
return import(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (const name of modules) {
|
for (const name of modules) {
|
||||||
try {
|
try {
|
||||||
/* eslint-disable-next-line @typescript-eslint/no-var-requires */
|
/* eslint-disable-next-line @typescript-eslint/no-var-requires */
|
||||||
const data: RuleSourceModule = r(name);
|
const data: RuleSourceModule = await loadModule(name);
|
||||||
if (!validateRules(ctx, data)) {
|
if (!validateRules(ctx, data)) {
|
||||||
ctx.logger.error({
|
ctx.logger.error({
|
||||||
module: name,
|
module: name,
|
||||||
|
@ -218,7 +228,7 @@ export async function resolveRules(rules: Array<Rule>, selector: RuleSelector):
|
||||||
}
|
}
|
||||||
|
|
||||||
export function validateRules(ctx: VisitorContext, root: any): boolean {
|
export function validateRules(ctx: VisitorContext, root: any): boolean {
|
||||||
const { definitions, name } = {} as any; // ruleSchemaData as any; // TODO: fix this
|
const { definitions, name } = { definitions: { config: {} } } as any; // ruleSchemaData as any;
|
||||||
|
|
||||||
const validCtx = new VisitorContext(ctx);
|
const validCtx = new VisitorContext(ctx);
|
||||||
validCtx.addSchema(name, definitions);
|
validCtx.addSchema(name, definitions);
|
||||||
|
@ -233,7 +243,7 @@ export function validateRules(ctx: VisitorContext, root: any): boolean {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function validateConfig(ctx: VisitorContext, root: any): boolean {
|
export function validateConfig(ctx: VisitorContext, root: any): boolean {
|
||||||
const { definitions, name } = {} as any; // ruleSchemaData as any;
|
const { definitions, name } = { definitions: { config: {} } } as any; // ruleSchemaData as any;
|
||||||
|
|
||||||
const validCtx = new VisitorContext(ctx);
|
const validCtx = new VisitorContext(ctx);
|
||||||
validCtx.addSchema(name, definitions);
|
validCtx.addSchema(name, definitions);
|
||||||
|
|
|
@ -3,6 +3,8 @@ import { LogLevel } from 'noicejs';
|
||||||
|
|
||||||
import { VisitorContext } from './VisitorContext.js';
|
import { VisitorContext } from './VisitorContext.js';
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a runtime error, not an exception.
|
* This is a runtime error, not an exception.
|
||||||
*/
|
*/
|
||||||
|
@ -20,7 +22,7 @@ export interface VisitorResult {
|
||||||
export interface Visitor<TResult extends VisitorResult = VisitorResult> {
|
export interface Visitor<TResult extends VisitorResult = VisitorResult> {
|
||||||
/**
|
/**
|
||||||
* Select nodes eligible to be visited.
|
* Select nodes eligible to be visited.
|
||||||
**/
|
*/
|
||||||
pick(ctx: VisitorContext, root: any): Promise<Array<any>>;
|
pick(ctx: VisitorContext, root: any): Promise<Array<any>>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,7 +2,9 @@ import { NotFoundError } from '@apextoaster/js-utils';
|
||||||
import { expect } from 'chai';
|
import { expect } from 'chai';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
|
||||||
import { loadConfig, readConfig } from '../../src/config/index.js';
|
import { dirName, loadConfig, readConfig } from '../../src/config/index.js';
|
||||||
|
|
||||||
|
const __dirname = dirName();
|
||||||
|
|
||||||
describe('load config helper', async () => {
|
describe('load config helper', async () => {
|
||||||
it('should load an existing config', async () =>
|
it('should load an existing config', async () =>
|
||||||
|
|
|
@ -3,11 +3,14 @@ import { vol } from 'memfs';
|
||||||
import { LogLevel, NullLogger } from 'noicejs';
|
import { LogLevel, NullLogger } from 'noicejs';
|
||||||
import { spy, stub } from 'sinon';
|
import { spy, stub } from 'sinon';
|
||||||
|
|
||||||
|
import { dirName } from '../../src/config/index.js';
|
||||||
import { loadRuleFiles, loadRuleModules, loadRulePaths, loadRuleSource } from '../../src/rule/index.js';
|
import { loadRuleFiles, loadRuleModules, loadRulePaths, loadRuleSource } from '../../src/rule/index.js';
|
||||||
import { SchemaRule } from '../../src/rule/SchemaRule.js';
|
import { SchemaRule } from '../../src/rule/SchemaRule.js';
|
||||||
import { Filesystem, setFs } from '../../src/source.js';
|
import { Filesystem, setFs } from '../../src/source.js';
|
||||||
import { VisitorContext } from '../../src/visitor/VisitorContext.js';
|
import { VisitorContext } from '../../src/visitor/VisitorContext.js';
|
||||||
|
|
||||||
|
const __dirname = dirName();
|
||||||
|
|
||||||
const EXAMPLE_EMPTY = '{name: foo, definitions: {}, rules: []}';
|
const EXAMPLE_EMPTY = '{name: foo, definitions: {}, rules: []}';
|
||||||
const EXAMPLE_RULES = `{
|
const EXAMPLE_RULES = `{
|
||||||
name: foo,
|
name: foo,
|
||||||
|
|
|
@ -467,9 +467,9 @@
|
||||||
source-map "^0.6.0"
|
source-map "^0.6.0"
|
||||||
|
|
||||||
"@types/yargs-parser@*":
|
"@types/yargs-parser@*":
|
||||||
version "13.1.0"
|
version "20.2.1"
|
||||||
resolved "https://artifacts.apextoaster.com/repository/group-npm/@types/yargs-parser/-/yargs-parser-13.1.0.tgz#c563aa192f39350a1d18da36c5a8da382bbd8228"
|
resolved "https://artifacts.apextoaster.com/repository/group-npm/@types/yargs-parser/-/yargs-parser-20.2.1.tgz#3b9ce2489919d9e4fea439b76916abc34b2df129"
|
||||||
integrity sha512-gCubfBUZ6KxzoibJ+SCUc/57Ms1jz5NjHe4+dI2krNmU5zCPAphyLJYyTOg06ueIyfj+SaCUqmzun7ImlxDcKg==
|
integrity sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==
|
||||||
|
|
||||||
"@types/yargs@17.0.8":
|
"@types/yargs@17.0.8":
|
||||||
version "17.0.8"
|
version "17.0.8"
|
||||||
|
|
Loading…
Reference in New Issue