Repository: stoplightio/spectral
Pull request #1560 (2021-03-25 23:01:33)

feat(cli): drop --skip-rule and --show-unmatched-globs flags
AFAIR `--skip-rule` had been added before custom rulesets, and now, when we also have exceptions, it just doesn't make any sense to keep that flag. You can simply create a custom ruleset and disable these rules manually.

**Checklist**

- [x] Tests added / updated
- [x] Docs added / updated

**Does this PR introduce a breaking change?**

- [x] Yes
- [ ] No





Patch:
diff --git a/docs/guides/2-cli.md b/docs/guides/2-cli.md
index 0b11d251..48f12bcd 100644
--- a/docs/guides/2-cli.md
+++ b/docs/guides/2-cli.md
@@ -29,14 +29,11 @@ Other options include:
   --output, -o                 output to a file instead of stdout                            [string]
   --resolver                   path to custom json-ref-resolver instance                     [string]
   --ruleset, -r                path/URL to a ruleset file                                    [string]
-  --skip-rule, -s              ignore certain rules if they are causing trouble              [string]
   --fail-severity, -F          results of this level or above will trigger a failure exit code
                                [string] [choices: "error", "warn", "info", "hint"] [default: "error"]
   --display-only-failures, -D  only output results equal to or greater than --fail-severity
                                                                            [boolean] [default: false]
   --ignore-unknown-format      do not warn about unmatched formats         [boolean] [default: false]
-  --show-unmatched-globs       show unmatched glob patterns
-                               [deprecated: use --fail-on-unmatched-globs] [boolean] [default: false]
   --fail-on-unmatched-globs    fail on unmatched glob patterns             [boolean] [default: false]
   --verbose, -v                increase verbosity                                           [boolean]
   --quiet, -q                  no logging - output only                                     [boolean]
diff --git a/docs/migration-guides/6.0.md b/docs/migration-guides/6.0.md
new file mode 100644
index 00000000..58739c91
--- /dev/null
+++ b/docs/migration-guides/6.0.md
@@ -0,0 +1,7 @@
+# Spectral v5 to v6 Migration Guide (WIP)
+
+## CLI
+
+1. deprecated `--show-unmatched-globs` flag has been removed. Alternative available: `--fail-on-unmatched-globs`
+
+2. `--skip-rule` has been removed. Use a custom ruleset instead.
diff --git a/src/cli/commands/lint.ts b/src/cli/commands/lint.ts
index eeb5da89..9451e179 100644
--- a/src/cli/commands/lint.ts
+++ b/src/cli/commands/lint.ts
@@ -81,12 +81,6 @@ const lintCommand: CommandModule = {
           type: 'string',
           coerce: toArray,
         },
-        'skip-rule': {
-          alias: 's',
-          description: 'ignore certain rules if they are causing trouble',
-          type: 'string',
-          coerce: toArray,
-        },
         'fail-severity': {
           alias: 'F',
           description: 'results of this level or above will trigger a failure exit code',
@@ -105,12 +99,6 @@ const lintCommand: CommandModule = {
           type: 'boolean',
           default: false,
         },
-        'show-unmatched-globs': {
-          description: 'show unmatched glob patterns',
-          type: 'boolean',
-          default: false,
-          deprecated: 'use --fail-on-unmatched-globs',
-        },
         'fail-on-unmatched-globs': {
           description: 'fail on unmatched glob patterns',
           type: 'boolean',
@@ -138,7 +126,6 @@ const lintCommand: CommandModule = {
       output,
       encoding,
       ignoreUnknownFormat,
-      showUnmatchedGlobs,
       failOnUnmatchedGlobs,
       ...config
     } = (args as unknown) as ILintConfig & {
@@ -153,9 +140,8 @@ const lintCommand: CommandModule = {
       encoding,
       ignoreUnknownFormat,
       failOnUnmatchedGlobs,
-      showUnmatchedGlobs,
       ruleset,
-      ...pick<Partial<ILintConfig>, keyof ILintConfig>(config, ['skipRule', 'verbose', 'quiet', 'resolver']),
+      ...pick<Partial<ILintConfig>, keyof ILintConfig>(config, ['verbose', 'quiet', 'resolver']),
     })
       .then(results => {
         if (displayOnlyFailures) {
diff --git a/src/cli/services/linter/linter.ts b/src/cli/services/linter/linter.ts
index fff15d71..7a5f0e1a 100644
--- a/src/cli/services/linter/linter.ts
+++ b/src/cli/services/linter/linter.ts
@@ -4,7 +4,7 @@ import { readParsable, IFileReadOptions } from '../../../fs/reader';
 import * as Parsers from '../../../parsers';
 import { IRuleResult, Spectral } from '../../../spectral';
 import { ILintConfig } from '../../../types/config';
-import { getRuleset, listFiles, skipRules, segregateEntriesPerKind, readFileDescriptor } from './utils';
+import { getRuleset, listFiles, segregateEntriesPerKind, readFileDescriptor } from './utils';
 import { getResolver } from './utils/getResolver';
 import { YamlParserResult } from '@stoplight/yaml';
 import { DEFAULT_REQUEST_OPTIONS } from '../../../request';
@@ -45,15 +45,8 @@ export async function lint(documents: Array<number | string>, flags: ILintConfig
     }
   }
 
-  if (flags.skipRule !== void 0) {
-    spectral.setRules(skipRules(ruleset.rules, flags));
-  }
-
   const [globs, fileDescriptors] = segregateEntriesPerKind(documents);
-  const [targetUris, unmatchedPatterns] = await listFiles(
-    globs,
-    !(flags.showUnmatchedGlobs || flags.failOnUnmatchedGlobs),
-  );
+  const [targetUris, unmatchedPatterns] = await listFiles(globs, !flags.failOnUnmatchedGlobs);
   const results: IRuleResult[] = [];
 
   if (unmatchedPatterns.length > 0) {
diff --git a/src/cli/services/linter/utils/index.ts b/src/cli/services/linter/utils/index.ts
index 23269b2a..8b1f5c4f 100644
--- a/src/cli/services/linter/utils/index.ts
+++ b/src/cli/services/linter/utils/index.ts
@@ -2,4 +2,3 @@ export * from './getRuleset';
 export * from './listFiles';
 export * from './readFileDescriptor';
 export * from './segregateEntriesPerKind';
-export * from './skipRules';
diff --git a/src/cli/services/linter/utils/skipRules.ts b/src/cli/services/linter/utils/skipRules.ts
deleted file mode 100644
index a937e437..00000000
--- a/src/cli/services/linter/utils/skipRules.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import { RuleCollection } from '../../../../types';
-import { ILintConfig } from '../../../../types/config';
-
-export const skipRules = (rules: RuleCollection, flags: ILintConfig): RuleCollection => {
-  const skippedRules: string[] = [];
-  const invalidRules: string[] = [];
-
-  if (flags.skipRule !== undefined) {
-    for (const rule of Array.isArray(flags.skipRule) ? flags.skipRule : [flags.skipRule]) {
-      if (rule in rules) {
-        delete rules[rule];
-        skippedRules.push(rule);
-      } else {
-        invalidRules.push(rule);
-      }
-    }
-  }
-
-  if (invalidRules.length !== 0 && !flags.quiet) {
-    console.warn(`ignoring invalid ${invalidRules.length > 1 ? 'rules' : 'rule'} "${invalidRules.join(', ')}"`);
-  }
-
-  if (skippedRules.length !== 0 && flags.verbose) {
-    console.info(`skipping ${skippedRules.length > 1 ? 'rules' : 'rule'} "${skippedRules.join(', ')}"`);
-  }
-
-  return rules;
-};
diff --git a/src/types/config.ts b/src/types/config.ts
index 2d8f0606..49296104 100644
--- a/src/types/config.ts
+++ b/src/types/config.ts
@@ -17,9 +17,7 @@ export interface ILintConfig {
   output?: string;
   resolver?: string;
   ruleset?: string[];
-  skipRule?: string[];
   ignoreUnknownFormat: boolean;
-  showUnmatchedGlobs: boolean;
   failOnUnmatchedGlobs: boolean;
   verbose?: boolean;
   quiet?: boolean;


Test patch:
diff --git a/src/cli/commands/__tests__/lint.test.ts b/src/cli/commands/__tests__/lint.test.ts
index 815717f9..4c12ba69 100644
--- a/src/cli/commands/__tests__/lint.test.ts
+++ b/src/cli/commands/__tests__/lint.test.ts
@@ -77,7 +77,6 @@ describe('lint', () => {
         encoding: 'utf8',
         format: 'stylish',
         ignoreUnknownFormat: false,
-        showUnmatchedGlobs: false,
         failOnUnmatchedGlobs: false,
       });
     });
@@ -95,7 +94,6 @@ describe('lint', () => {
       encoding: 'utf8',
       format: 'stylish',
       ignoreUnknownFormat: false,
-      showUnmatchedGlobs: false,
       failOnUnmatchedGlobs: false,
     });
   });
@@ -107,7 +105,6 @@ describe('lint', () => {
       encoding: 'utf16',
       format: 'stylish',
       ignoreUnknownFormat: false,
-      showUnmatchedGlobs: false,
       failOnUnmatchedGlobs: false,
     });
   });
@@ -119,7 +116,6 @@ describe('lint', () => {
       encoding: 'utf16',
       format: 'json',
       ignoreUnknownFormat: false,
-      showUnmatchedGlobs: false,
       failOnUnmatchedGlobs: false,
     });
   });
@@ -161,36 +157,12 @@ describe('lint', () => {
     expect(writeOutput).toBeCalledWith('<formatted output>', 'foo.json');
   });
 
-  it('passes skip-rule to lint', async () => {
-    await run('lint --skip-rule foo --skip-rule bar ./__fixtures__/empty-oas2-document.json');
-    expect(lint).toHaveBeenCalledWith([expect.any(String)], {
-      skipRule: ['foo', 'bar'],
-      encoding: 'utf8',
-      format: 'stylish',
-      ignoreUnknownFormat: false,
-      showUnmatchedGlobs: false,
-      failOnUnmatchedGlobs: false,
-    });
-  });
-
   it('passes ignore-unknown-format to lint', async () => {
     await run('lint --ignore-unknown-format ./__fixtures__/empty-oas2-document.json');
     expect(lint).toHaveBeenCalledWith([expect.any(String)], {
       encoding: 'utf8',
       format: 'stylish',
       ignoreUnknownFormat: true,
-      showUnmatchedGlobs: false,
-      failOnUnmatchedGlobs: false,
-    });
-  });
-
-  it('passes show-unmatched-globs to lint', async () => {
-    await run('lint --show-unmatched-globs ./__fixtures__/empty-oas2-document.json');
-    expect(lint).toHaveBeenCalledWith([expect.any(String)], {
-      encoding: 'utf8',
-      format: 'stylish',
-      ignoreUnknownFormat: false,
-      showUnmatchedGlobs: true,
       failOnUnmatchedGlobs: false,
     });
   });
@@ -201,7 +173,6 @@ describe('lint', () => {
       encoding: 'utf8',
       format: 'stylish',
       ignoreUnknownFormat: false,
-      showUnmatchedGlobs: false,
       failOnUnmatchedGlobs: true,
     });
   });
diff --git a/src/cli/services/__tests__/linter.test.ts b/src/cli/services/__tests__/linter.test.ts
index 2fcc83b6..a045b07d 100644
--- a/src/cli/services/__tests__/linter.test.ts
+++ b/src/cli/services/__tests__/linter.test.ts
@@ -129,24 +129,6 @@ describe('Linter service', () => {
           ]),
         );
       });
-
-      describe('and --skip-rule=info-contact is set', () => {
-        it('output other warnings but not info-contact', async () => {
-          const output = await run(`lint --skip-rule=info-contact ${document}`);
-
-          expect(output).toEqual(expect.arrayContaining([expect.objectContaining({ code: 'oas3-api-servers' })]));
-          expect(output).toEqual(expect.not.arrayContaining([expect.objectContaining({ code: 'info-contact' })]));
-        });
-      });
-
-      describe('and --skip-rule=info-contact --skip-rule=oas3-api-servers is set', () => {
-        it('outputs neither info-contact or oas3-api-servers', async () => {
-          const output = await run(`lint --skip-rule=info-contact --skip-rule=oas3-api-servers ${document}`);
-
-          expect(output).toEqual(expect.not.arrayContaining([expect.objectContaining({ code: 'info-contact' })]));
-          expect(output).toEqual(expect.not.arrayContaining([expect.objectContaining({ code: 'oas3-api-servers' })]));
-        });
-      });
     });
   });
 
diff --git a/test-harness/scenarios/help-no-document.scenario b/test-harness/scenarios/help-no-document.scenario
index 4fd2def7..e9dacf0d 100644
--- a/test-harness/scenarios/help-no-document.scenario
+++ b/test-harness/scenarios/help-no-document.scenario
@@ -18,11 +18,9 @@ Options:
   -o, --output                   output to a file instead of stdout  [string]
       --resolver                 path to custom json-ref-resolver instance  [string]
   -r, --ruleset                  path/URL to a ruleset file  [string]
-  -s, --skip-rule                ignore certain rules if they are causing trouble  [string]
   -F, --fail-severity            results of this level or above will trigger a failure exit code  [string] [choices: "error", "warn", "info", "hint"] [default: "error"]
   -D, --display-only-failures    only output results equal to or greater than --fail-severity  [boolean] [default: false]
       --ignore-unknown-format    do not warn about unmatched formats  [boolean] [default: false]
-      --show-unmatched-globs     show unmatched glob patterns  [deprecated: use --fail-on-unmatched-globs] [boolean] [default: false]
       --fail-on-unmatched-globs  fail on unmatched glob patterns  [boolean] [default: false]
   -v, --verbose                  increase verbosity  [boolean]
   -q, --quiet                    no logging - output only  [boolean]
diff --git a/test-harness/scenarios/results-skip-rule.oas3.scenario b/test-harness/scenarios/results-skip-rule.oas3.scenario
deleted file mode 100644
index 1fd99766..00000000
--- a/test-harness/scenarios/results-skip-rule.oas3.scenario
+++ /dev/null
@@ -1,18 +0,0 @@
-====test====
-Can skip a rule with --skip-rule=info-contact
-====document====
-openapi: 3.0.0
-info:
-  version: 1.0.0
-  title: Stoplight
-paths: {}
-====command====
-{bin} lint {document} --skip-rule=info-contact
-====stdout====
-OpenAPI 3.x detected
-
-{document}
- 1:1  warning  oas3-api-servers  OpenAPI `servers` must be present and non-empty array.
- 2:6  warning  info-description  OpenAPI object info `description` must be present and non-empty string.  info
-
-✖ 2 problems (0 errors, 2 warnings, 0 infos, 0 hints)
diff --git a/test-harness/scenarios/results-skip-rules-multiple.oas3.scenario b/test-harness/scenarios/results-skip-rules-multiple.oas3.scenario
deleted file mode 100644
index 091f846f..00000000
--- a/test-harness/scenarios/results-skip-rules-multiple.oas3.scenario
+++ /dev/null
@@ -1,17 +0,0 @@
-====test====
-Can skip multiple rules
-====document====
-openapi: 3.0.0
-info:
-  version: 1.0.0
-  title: Stoplight
-paths: {}
-====command====
-{bin} lint {document} --skip-rule=info-contact --skip-rule=info-description
-====stdout====
-OpenAPI 3.x detected
-
-{document}
- 1:1  warning  oas3-api-servers  OpenAPI `servers` must be present and non-empty array.
-
-✖ 1 problem (0 errors, 1 warning, 0 infos, 0 hints)
diff --git a/test-harness/scenarios/unmatched-glob-patterns.scenario b/test-harness/scenarios/unmatched-glob-patterns.scenario
deleted file mode 100644
index 3a309c34..00000000
--- a/test-harness/scenarios/unmatched-glob-patterns.scenario
+++ /dev/null
@@ -1,7 +0,0 @@
-====test====
-Reports unmatched glob patterns
-====command====
-{bin} lint ./*oops.{yml,yaml,json} --show-unmatched-globs
-====stdout====
-Glob pattern `./*oops.{yml,yaml,json}` did not match any files
-No results with a severity of 'error' or higher found!