From 8f5055aea5b37b470e4c28c726218ff4234e792a Mon Sep 17 00:00:00 2001 From: ouvreboite Date: Fri, 14 Jun 2024 11:56:38 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Manage=20subdirectory=20for=20rules?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/valid/README.md | 26 ++++++------ examples/valid/rules1.md | 18 -------- examples/valid/spectral.yaml | 24 +++++------ examples/valid/subdirectory/subrules.md | 55 +++++++++++++++++++++++++ src/functions.js | 9 ++-- 5 files changed, 86 insertions(+), 46 deletions(-) create mode 100644 examples/valid/subdirectory/subrules.md diff --git a/examples/valid/README.md b/examples/valid/README.md index 5045d54..5139448 100644 --- a/examples/valid/README.md +++ b/examples/valid/README.md @@ -1,6 +1,6 @@ # Valid example -* This example contains rules accross several markdown files: [rules1.md](rules1.md) and [rules2.md](rules2.md) +* This example contains rules accross several markdown files: [rules1.md](rules1.md) and [rules2.md](rules2.md) and even subdirectories [subdirectory/subrules.md](subdirectory/subrules.md) * ✅ All the test declared in those files are expected to pass * Some of the rules use custom functions defined in the [functions](functions) directory * [spectral.base.yaml](spectral.base.yaml) contains the base rule files that will be used to merge the rules into. For example, it contains the extends, aliases and functions declarations @@ -9,21 +9,23 @@ ## Test ouput ``` -npx poltergust test .\examples\valid +npx poltergust .\examples\valid 🔎 Testing the spectral rules from the .md files in the directory: .\examples\valid -👻 base-path-must-start-with-slash (examples\valid\rules1.md:40) - ✅ Test OK (examples\valid\rules1.md:17) - ✅ Test OK (examples\valid\rules1.md:27) -👻 operation-parameters-must-have-description (examples\valid\rules1.md:91) - ✅ Test OK (examples\valid\rules1.md:58) - ✅ Test OK (examples\valid\rules1.md:73) -👻 operation-must-have-description (examples\valid\rules1.md:107) -👻 operation-must-have-no-summary (examples\valid\rules1.md:122) -👻 operation-must-have-at-least-one-response (examples\valid\rules1.md:135) -👻 request-bodies-must-have-a-content (examples\valid\rules1.md:152) +👻 base-path-must-start-with-slash (examples\valid\rules1.md:39) + ✅ Test OK (examples\valid\rules1.md:16) + ✅ Test OK (examples\valid\rules1.md:26) +👻 operation-parameters-must-have-description (examples\valid\rules1.md:90) + ✅ Test OK (examples\valid\rules1.md:57) + ✅ Test OK (examples\valid\rules1.md:72) +👻 operation-must-have-description (examples\valid\rules1.md:106) +👻 operation-must-have-no-summary (examples\valid\rules1.md:121) +👻 operation-must-have-at-least-one-response (examples\valid\rules1.md:134) 👻 path-parameters-must-be-kebab-case (examples\valid\rules2.md:49) ✅ Test OK (examples\valid\rules2.md:11) 👻 required-property-must-exist (examples\valid\rules2.md:96) ✅ Test OK (examples\valid\rules2.md:66) +👻 request-bodies-must-have-a-content (examples\valid\subdirectory\subrules.md:41) + ✅ Test OK (examples\valid\subdirectory\subrules.md:8) + ✅ Test OK (examples\valid\subdirectory\subrules.md:25) ✅ Spectral rules merged in the file: examples\valid\spectral.yaml ``` \ No newline at end of file diff --git a/examples/valid/rules1.md b/examples/valid/rules1.md index 6db0b41..e66ca83 100644 --- a/examples/valid/rules1.md +++ b/examples/valid/rules1.md @@ -5,7 +5,6 @@ 3. [operation-must-have-description](#operation-must-have-description) 4. [operation-must-have-no-summary](#operation-must-have-no-summary) 5. [operation-must-have-at-least-one-response](#operation-must-have-at-least-one-response) -6. [request-bodies-must-have-a-content](#request-bodies-must-have-a-content) ## base-path-must-start-with-slash @@ -144,21 +143,4 @@ operation-must-have-at-least-one-response: function: length functionOptions: min: 1 -``` - -## request-bodies-must-have-a-content - -```yaml -#👻-rule -request-bodies-must-have-a-content: - description: Request bodies must have a content - given: $.paths[*][*].requestBody - severity: error - then: - - field: content - function: truthy - - field: content - function: length - functionOptions: - min: 1 ``` \ No newline at end of file diff --git a/examples/valid/spectral.yaml b/examples/valid/spectral.yaml index 6bf1d81..2dd966d 100644 --- a/examples/valid/spectral.yaml +++ b/examples/valid/spectral.yaml @@ -55,18 +55,6 @@ rules: functionOptions: min: 1 - request-bodies-must-have-a-content: - description: Request bodies must have a content - given: $.paths[*][*].requestBody - severity: error - then: - - field: content - function: truthy - - field: content - function: length - functionOptions: - min: 1 - path-parameters-must-be-kebab-case: description: Path parameters must be kebab case given: "#parameters[?(@.in==\"path\")]" @@ -84,4 +72,16 @@ rules: severity: error then: function: isRequiredPropertyDefined + + request-bodies-must-have-a-content: + description: Request bodies must have a content + given: $.paths[*][*].requestBody + severity: error + then: + - field: content + function: truthy + - field: content + function: length + functionOptions: + min: 1 \ No newline at end of file diff --git a/examples/valid/subdirectory/subrules.md b/examples/valid/subdirectory/subrules.md new file mode 100644 index 0000000..26d237e --- /dev/null +++ b/examples/valid/subdirectory/subrules.md @@ -0,0 +1,55 @@ +# Parameters rules + +1. [request-bodies-must-have-a-content](#request-bodies-must-have-a-content) + +## request-bodies-must-have-a-content + +```yaml +#👻-failures: 0 request-bodies-must-have-a-content +openapi: 3.0.1 +paths: + /pets: + post: + requestBody: + required: true + content: + application/json: + schema: + type: string + responses: + '201': + description: Created +``` + +```yaml +#👻-failures: 1 request-bodies-must-have-a-content +openapi: 3.0.1 +paths: + /pets: + post: + requestBody: #👻-fails-here: request-bodies-must-have-a-content + required: true + responses: + '201': + description: Created +``` + +
+ Spectral rule 🤖 + +```yaml +#👻-rule +request-bodies-must-have-a-content: + description: Request bodies must have a content + given: $.paths[*][*].requestBody + severity: error + then: + - field: content + function: truthy + - field: content + function: length + functionOptions: + min: 1 +``` + +
\ No newline at end of file diff --git a/src/functions.js b/src/functions.js index ebb0eba..10f109b 100644 --- a/src/functions.js +++ b/src/functions.js @@ -7,10 +7,11 @@ import { bundleAndLoadRuleset } from "@stoplight/spectral-ruleset-bundler/with-l /** * @param {string} rulesDir - * @returns {Object.} the spectral rules and test cases by rule name + * @returns {Object.} the spectral rules and test cases by rule name */ export function extractAllRulesAndTestCases(rulesDir) { - const markdownFiles = fs.readdirSync(rulesDir).filter(f => f.endsWith('.md')); + //find all markdown files in the rules directory and subdirectories + const markdownFiles = fs.readdirSync(rulesDir, {encoding: "utf8", recursive: true}).filter(f => f.endsWith('.md')); /** @type {Object.} */ let byRuleName = {}; @@ -34,14 +35,14 @@ export function extractAllRulesAndTestCases(rulesDir) { /** * @param {string} filePath - * @param {Object.} byRuleName + * @param {Object.} byRuleName */ export function extractRulesAndTestCases(filePath, byRuleName) { const blocks = extractYamlBlocks(filePath); blocks.forEach(block => { const rule = extractRuleFromBlock(block, filePath); - const testCase = extractTestCaseBlock(block, filePath); + const testCase = extractTestCaseBlock(block); //invalid states if(!rule && !testCase){