Skip to content

Commit

Permalink
feat(cli): hook up ruleset-migrator
Browse files Browse the repository at this point in the history
  • Loading branch information
P0lip committed Jun 28, 2021
1 parent 8e50fcf commit 303a321
Show file tree
Hide file tree
Showing 9 changed files with 55 additions and 38 deletions.
1 change: 1 addition & 0 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"@stoplight/json": "3.15.0",
"@stoplight/path": "1.3.2",
"@stoplight/spectral-core": "^0.0.0",
"@stoplight/spectral-ruleset-migrator": "^0.0.0",
"@stoplight/spectral-parsers": "^0.0.0",
"@stoplight/spectral-ref-resolver": "^0.0.0",
"@stoplight/spectral-runtime": "^0.0.0",
Expand Down
41 changes: 35 additions & 6 deletions packages/cli/src/services/linter/utils/getRuleset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@ import { Optional } from '@stoplight/types';
import { Ruleset, RulesetDefinition } from '@stoplight/spectral-core';
import * as fs from 'fs';
import * as path from '@stoplight/path';
import { isAbsolute } from '@stoplight/path';
import * as process from 'process';
import { extname } from '@stoplight/path';
import { migrateRuleset } from '@stoplight/spectral-ruleset-migrator';

const DEFAULT_RULESET_FILE = /^\.?spectral\.(ya?ml|json|m?js)$/;

// eslint-disable-next-line @typescript-eslint/require-await
const AsyncFunction = (async (): Promise<void> => void 0).constructor as FunctionConstructor;

async function getDefaultRulesetFile(): Promise<Optional<string>> {
const cwd = process.cwd();
for (const filename of await fs.promises.readdir(cwd)) {
if (Ruleset.isDefaultRulesetFile(filename)) {
if (DEFAULT_RULESET_FILE.test(filename)) {
return path.join(cwd, filename);
}
}
Expand All @@ -19,17 +25,40 @@ async function getDefaultRulesetFile(): Promise<Optional<string>> {
export async function getRuleset(rulesetFile: Optional<string>): Promise<Ruleset> {
if (rulesetFile === void 0) {
rulesetFile = await getDefaultRulesetFile();
} else if (!isAbsolute(rulesetFile)) {
} else if (!path.isAbsolute(rulesetFile)) {
rulesetFile = path.join(process.cwd(), rulesetFile);
}

if (rulesetFile === void 0) {
return new Ruleset({ rules: {} });
throw new Error('No ruleset has been provided');
}

const ruleset = (await import(rulesetFile)) as { default: RulesetDefinition } | RulesetDefinition;
let ruleset;

if (/(json|ya?ml)$/.test(extname(rulesetFile))) {
const m: { exports?: RulesetDefinition } = {};
const paths = [path.dirname(rulesetFile)];

await AsyncFunction(
'module, require',
await migrateRuleset(rulesetFile, {
cwd: process.cwd(),
format: 'commonjs',
fs,
}),
// eslint-disable-next-line @typescript-eslint/no-var-requires
)(m, (id: string) => require(require.resolve(id, { paths })) as unknown);

ruleset = m.exports;
} else {
const imported = (await import(rulesetFile)) as { default: unknown } | unknown;
ruleset =
typeof imported === 'object' && imported !== null && 'default' in imported
? (imported as Record<'default', unknown>).default
: imported;
}

return new Ruleset('default' in ruleset ? ruleset.default : ruleset, {
return new Ruleset(ruleset, {
severity: 'recommended',
source: rulesetFile,
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
====test====
Reports unmatched glob patterns
====asset:ruleset====
rules: {}
====command====
{bin} lint ./*oops.{yml,yaml,json} --fail-on-unmatched-globs
{bin} lint ./*oops.{yml,yaml,json} --fail-on-unmatched-globs --ruleset {asset:ruleset}
====status====
2
====stderr====
Expand Down
7 changes: 2 additions & 5 deletions test-harness/scenarios/oas3.1/json-schema-dialect.scenario
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,13 @@ info:
version: 1.0.0
jsonSchemaDialect:
paths: {}
====asset:ruleset====
====asset:ruleset.yaml====
extends: [[spectral:oas, off]]
rules:
oas3-schema: error
====command====
{bin} lint {document} --ruleset {asset:ruleset}
{bin} lint {document} --ruleset {asset:ruleset.yaml}
====stdout====
OpenAPI 3.x detected
OpenAPI 3.1.x detected

{document}
5:19 error oas3-schema `jsonSchemaDialect` property type must be string. jsonSchemaDialect

Expand Down
7 changes: 2 additions & 5 deletions test-harness/scenarios/oas3.1/missing-top-property.scenario
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,13 @@ openapi: 3.1.0
info:
title: no paths
version: 1.0.0
====asset:ruleset====
====asset:ruleset.yaml====
extends: [[spectral:oas, off]]
rules:
oas3-schema: error
====command====
{bin} lint {document} --ruleset {asset:ruleset}
{bin} lint {document} --ruleset {asset:ruleset.yaml}
====stdout====
OpenAPI 3.x detected
OpenAPI 3.1.x detected

{document}
1:1 error oas3-schema The document must have either `paths`, `webhooks` or `components`.

Expand Down
6 changes: 2 additions & 4 deletions test-harness/scenarios/oas3.1/paths-not-required.scenario
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@ info:
title: no paths
version: 1.0.0
webhooks: {}
====asset:ruleset====
====asset:ruleset.yaml====
extends: [[spectral:oas, off]]
rules:
oas3-schema: error
====command====
{bin} lint {document} --ruleset {asset:ruleset}
{bin} lint {document} --ruleset {asset:ruleset.yaml}
====stdout====
OpenAPI 3.x detected
OpenAPI 3.1.x detected
No results with a severity of 'error' or higher found!
16 changes: 5 additions & 11 deletions test-harness/scenarios/oas3.1/petstore.scenario
Original file line number Diff line number Diff line change
Expand Up @@ -179,17 +179,11 @@ components:
exclusiveMinimum: 18
examples:
- 36
====asset:ruleset====
const { oas } = require('@stoplight/spectral-rulesets');
module.exports = {
extends: [[oas, 'off']],
rules: {
'oas3-schema': 'error'
}
};
====asset:ruleset.yaml====
extends: [[spectral:oas, off]]
rules:
oas3-schema: error
====command====
{bin} lint {document} --ruleset {asset:ruleset}
{bin} lint {document} --ruleset {asset:ruleset.yaml}
====stdout====
OpenAPI 3.x detected
OpenAPI 3.1.x detected
No results with a severity of 'error' or higher found!
7 changes: 2 additions & 5 deletions test-harness/scenarios/oas3.1/webooks.scenario
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,13 @@ info:
webhooks:
invalidNewPet:
foo:
====asset:ruleset====
====asset:ruleset.yaml====
extends: [[spectral:oas, off]]
rules:
oas3-schema: error
====command====
{bin} lint {document} --ruleset {asset:ruleset}
{bin} lint {document} --ruleset {asset:ruleset.yaml}
====stdout====
OpenAPI 3.x detected
OpenAPI 3.1.x detected

{document}
7:17 error oas3-schema `invalidNewPet` property must not have unevaluated properties. webhooks.invalidNewPet

Expand Down
4 changes: 3 additions & 1 deletion test-harness/scenarios/proxy-agent.scenario
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ foo:
$ref: http://localhost:3002/foo.json#/ref
====env====
PROXY=http://localhost:3001
====asset:ruleset====
rules: {}
====command====
{bin} lint {document} --ignore-unknown-format
{bin} lint {document} --ignore-unknown-format --ruleset {asset:ruleset}
====stdout====
{document}
2:9 error invalid-ref FetchError: request to http://localhost:3002/foo.json failed, reason: connect ECONNREFUSED 127.0.0.1:3001 foo.$ref
Expand Down

0 comments on commit 303a321

Please sign in to comment.