From 59e7c138c075968c2b51d80e2d120c8f60423b14 Mon Sep 17 00:00:00 2001 From: ssube Date: Sat, 2 Nov 2019 07:48:12 -0500 Subject: [PATCH] fix: build a rule selector from args, log it in list mode --- src/index.ts | 10 +++++----- src/rule/SchemaRule.ts | 34 ---------------------------------- src/rule/index.ts | 40 +++++++++++++++++++++++++++++++++++++--- test/rule/TestRule.ts | 16 ++++++++-------- 4 files changed, 50 insertions(+), 50 deletions(-) diff --git a/src/index.ts b/src/index.ts index 44ae30b..32ffd64 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,8 +3,7 @@ import { createLogger } from 'bunyan'; import { loadConfig } from './config'; import { CONFIG_ARGS_NAME, CONFIG_ARGS_PATH, parseArgs } from './config/args'; import { YamlParser } from './parser/YamlParser'; -import { loadRules, resolveRules } from './rule'; -import { visitRules } from './rule/SchemaRule'; +import { createRuleSelector, loadRules, resolveRules, visitRules } from './rule'; import { loadSource, writeSource } from './source'; import { VERSION_INFO } from './version'; import { VisitorContext } from './visitor/VisitorContext'; @@ -44,11 +43,12 @@ export async function main(argv: Array): Promise { logger, }); - const rules = await loadRules(args.rules, ctx); - const activeRules = await resolveRules(rules, args); + const selector = createRuleSelector(args); + const loadedRules = await loadRules(args.rules, ctx); + const activeRules = await resolveRules(loadedRules, selector); if (mode === 'list') { - logger.info({ rules: activeRules }, 'listing active rules'); + logger.info({ rules: activeRules, selector }, 'listing active rules'); return STATUS_SUCCESS; } diff --git a/src/rule/SchemaRule.ts b/src/rule/SchemaRule.ts index c6e7d67..4c59e00 100644 --- a/src/rule/SchemaRule.ts +++ b/src/rule/SchemaRule.ts @@ -1,5 +1,4 @@ import { ValidateFunction } from 'ajv'; -import { applyDiff, diff } from 'deep-diff'; import { JSONPath } from 'jsonpath-plus'; import { cloneDeep, defaultTo, isNil } from 'lodash'; import { LogLevel } from 'noicejs'; @@ -85,36 +84,3 @@ export class SchemaRule implements RuleData, Visitor { } } } - -export async function visitRules(ctx: VisitorContext, rules: Array, data: any): Promise { - for (const rule of rules) { - const items = await rule.pick(ctx, data); - for (const item of items) { - const itemResult = cloneDeep(item); - const ruleResult = await rule.visit(ctx, itemResult); - - if (ruleResult.errors.length > 0) { - ctx.logger.warn({ count: ruleResult.errors.length, rule }, 'rule failed'); - ctx.mergeResult(ruleResult); - continue; - } - - const itemDiff = diff(item, itemResult); - if (hasItems(itemDiff)) { - ctx.logger.info({ - diff: itemDiff, - item, - rule: rule.name, - }, 'rule passed with modifications'); - - if (ctx.innerOptions.mutate) { - applyDiff(item, itemResult); - } - } else { - ctx.logger.info({ rule: rule.name }, 'rule passed'); - } - } - } - - return ctx; -} diff --git a/src/rule/index.ts b/src/rule/index.ts index 4275fe3..8451b9a 100644 --- a/src/rule/index.ts +++ b/src/rule/index.ts @@ -1,9 +1,10 @@ -import { Dictionary, intersection, isNil } from 'lodash'; +import { applyDiff, diff } from 'deep-diff'; +import { cloneDeep, Dictionary, intersection, isNil } from 'lodash'; import { LogLevel } from 'noicejs'; import { YamlParser } from '../parser/YamlParser'; import { readFile } from '../source'; -import { ensureArray } from '../utils'; +import { ensureArray, hasItems } from '../utils'; import { VisitorContext } from '../visitor/VisitorContext'; import { SchemaRule } from './SchemaRule'; @@ -36,7 +37,7 @@ export interface RuleSource { rules: Array; } -export function makeSelector(options: Partial) { +export function createRuleSelector(options: Partial) { return { excludeLevel: ensureArray(options.excludeLevel), excludeName: ensureArray(options.excludeName), @@ -103,3 +104,36 @@ export async function resolveRules(rules: Array, selector: RuleSelec return Array.from(activeRules); } + +export async function visitRules(ctx: VisitorContext, rules: Array, data: any): Promise { + for (const rule of rules) { + const items = await rule.pick(ctx, data); + for (const item of items) { + const itemResult = cloneDeep(item); + const ruleResult = await rule.visit(ctx, itemResult); + + if (ruleResult.errors.length > 0) { + ctx.logger.warn({ count: ruleResult.errors.length, rule }, 'rule failed'); + ctx.mergeResult(ruleResult); + continue; + } + + const itemDiff = diff(item, itemResult); + if (hasItems(itemDiff)) { + ctx.logger.info({ + diff: itemDiff, + item, + rule: rule.name, + }, 'rule passed with modifications'); + + if (ctx.innerOptions.mutate) { + applyDiff(item, itemResult); + } + } else { + ctx.logger.info({ rule: rule.name }, 'rule passed'); + } + } + } + + return ctx; +} diff --git a/test/rule/TestRule.ts b/test/rule/TestRule.ts index 5f9e797..4f09f55 100644 --- a/test/rule/TestRule.ts +++ b/test/rule/TestRule.ts @@ -2,8 +2,8 @@ import { expect } from 'chai'; import { ConsoleLogger } from 'noicejs'; import { mock, spy } from 'sinon'; -import { makeSelector, resolveRules } from '../../src/rule'; -import { SchemaRule, visitRules } from '../../src/rule/SchemaRule'; +import { createRuleSelector, resolveRules, visitRules } from '../../src/rule'; +import { SchemaRule } from '../../src/rule/SchemaRule'; import { VisitorContext } from '../../src/visitor/VisitorContext'; import { describeLeaks, itLeaks } from '../helpers/async'; @@ -33,7 +33,7 @@ const TEST_RULES = [new SchemaRule({ describeLeaks('rule resolver', async () => { describeLeaks('include by level', async () => { itLeaks('should include info rules', async () => { - const info = await resolveRules(TEST_RULES, makeSelector({ + const info = await resolveRules(TEST_RULES, createRuleSelector({ includeLevel: ['info'], })); @@ -42,7 +42,7 @@ describeLeaks('rule resolver', async () => { }); itLeaks('should include warn rules', async () => { - const info = await resolveRules(TEST_RULES, makeSelector({ + const info = await resolveRules(TEST_RULES, createRuleSelector({ includeLevel: ['warn'], })); @@ -54,7 +54,7 @@ describeLeaks('rule resolver', async () => { describeLeaks('include by name', async () => { itLeaks('should include foo rules', async () => { - const rules = await resolveRules(TEST_RULES, makeSelector({ + const rules = await resolveRules(TEST_RULES, createRuleSelector({ includeName: ['foo'], })); @@ -65,7 +65,7 @@ describeLeaks('rule resolver', async () => { describeLeaks('include by tag', async () => { itLeaks('should include test rules', async () => { - const rules = await resolveRules(TEST_RULES, makeSelector({ + const rules = await resolveRules(TEST_RULES, createRuleSelector({ includeTag: ['test'], })); @@ -77,7 +77,7 @@ describeLeaks('rule resolver', async () => { describeLeaks('exclude by name', async () => { itLeaks('should exclude foo rules', async () => { - const rules = await resolveRules(TEST_RULES, makeSelector({ + const rules = await resolveRules(TEST_RULES, createRuleSelector({ excludeName: ['foo'], includeTag: ['all'], })); @@ -90,7 +90,7 @@ describeLeaks('rule resolver', async () => { describeLeaks('exclude by tag', async () => { itLeaks('should exclude test rules', async () => { - const rules = await resolveRules(TEST_RULES, makeSelector({ + const rules = await resolveRules(TEST_RULES, createRuleSelector({ excludeTag: ['test'], includeTag: ['all'], }));