Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into lintlike-disable-re…
Browse files Browse the repository at this point in the history
…ports
  • Loading branch information
nex3 committed Oct 9, 2020
2 parents f1fd8ff + 69d4896 commit 2c392c6
Show file tree
Hide file tree
Showing 66 changed files with 605 additions and 257 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Expand Up @@ -6,6 +6,10 @@ All notable changes to this project are documented in this file.

- Added: disable comments that are reported as errors for various reasons are now reported as standard lint errors rather than a separate class of errors that must be handled specially.
- Deprecated: `StylelintStandaloneReturnValue.reportedDisables`, `.descriptionlessDisables`, `.needlessDisables`, and `.invalidScopeDisables`. `.reportedDisables` will always be empty and the other properties will always be undefined, since these errors now show up in `.results` instead.

## 13.7.2

- Fixed: regression for disable commands and adjacent double-slash comments ([#4950](https://github.com/stylelint/stylelint/pull/4950)).
- Fixed: use of full file path without converting it to glob ([#4931](https://github.com/stylelint/stylelint/pull/4931)).

## 13.7.1
Expand Down
4 changes: 3 additions & 1 deletion docs/user-guide/configure.md
Expand Up @@ -137,7 +137,7 @@ Reporters may use these severity levels to display violations or exit the proces

### `reportDisables`

You can set the `reportDisables` secondary option to report any disable comments for this rule, effectively disallowing authors to opt out of it.
You can set the `reportDisables` secondary option to report any `stylelint-disable` comments for this rule, effectively disallowing authors to opt out of it.

For example:

Expand All @@ -155,6 +155,8 @@ For example:
}
```

The report is considered to be a lint error.

## `defaultSeverity`

You can set the default severity level for all rules that do not have a severity specified in their secondary options. For example, you can set the default severity to `"warning"`:
Expand Down
1 change: 1 addition & 0 deletions docs/user-guide/rules/list.md
Expand Up @@ -209,6 +209,7 @@ Grouped first by the following categories and then by the [_thing_](http://apps.
- [`media-feature-name-disallowed-list`](../../../lib/rules/media-feature-name-disallowed-list/README.md): Specify a list of disallowed media feature names.
- [`media-feature-name-no-vendor-prefix`](../../../lib/rules/media-feature-name-no-vendor-prefix/README.md): Disallow vendor prefixes for media feature names (Autofixable).
- [`media-feature-name-value-allowed-list`](../../../lib/rules/media-feature-name-value-allowed-list/README.md): Specify a list of allowed media feature name and value pairs.
- [`media-feature-name-value-whitelist`](../../../lib/rules/media-feature-name-value-whitelist/README.md): Specify a list of allowed media feature name and value pairs. **(deprecated)**
- [`media-feature-name-whitelist`](../../../lib/rules/media-feature-name-whitelist/README.md): Specify a list of allowed media feature names. **(deprecated)**

### Custom media
Expand Down
43 changes: 41 additions & 2 deletions docs/user-guide/usage/options.md
Expand Up @@ -141,7 +141,7 @@ You can use this option to see what your linting results would be like without t

CLI flags: `--report-needless-disables, --rd`

Produce a report to clean up your codebase, keeping only the stylelint-disable comments that serve a purpose.
Produce a report to clean up your codebase, keeping only the `stylelint-disable` comments that serve a purpose.

If needless disables are found, the:

Expand All @@ -152,13 +152,52 @@ If needless disables are found, the:

CLI flags: `--report-invalid-scope-disables, --risd`

Produce a report of the stylelint-disable comments that used for rules that don't exist within the configuration object.
Produce a report of the `stylelint-disable` comments that used for rules that don't exist within the configuration object.

If invalid scope disables are found, the:

- CLI process exits with code `2`
- Node.js API adds errors to the returned data

## `reportDescriptionlessDisables`

CLI flags: `--report-descriptionless-disables, --rdd`

Produce a report of the `stylelint-disable` comments without a description.

For example, when the configuration `{ block-no-empty: true }` is given, the following patterns are reported:

<!-- prettier-ignore -->
```css
/* stylelint-disable */
a {}
```

<!-- prettier-ignore -->
```css
/* stylelint-disable-next-line block-no-empty */
a {}
```

But, the following patterns (`stylelint-disable -- <description>`) are _not_ reported:

<!-- prettier-ignore -->
```css
/* stylelint-disable -- This violation is ignorable. */
a {}
```

<!-- prettier-ignore -->
```css
/* stylelint-disable-next-line block-no-empty -- This violation is ignorable. */
a {}
```

If descriptionless disables are found, the:

- CLI process exits with code `2`
- Node.js API adds errors to the returned data

## `codeFilename`

CLI flag: `--stdin-filename`
Expand Down
147 changes: 146 additions & 1 deletion lib/__tests__/disableRanges.test.js
@@ -1,11 +1,13 @@
'use strict';

const assignDisabledRanges = require('../assignDisabledRanges');
const _ = require('lodash');
const assignDisabledRanges = require('../assignDisabledRanges');
const less = require('postcss-less');
const postcss = require('postcss');
const scss = require('postcss-scss');

/* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect*"] }] */

it('no disabling', () => {
return testDisableRanges('a {}').then((result) => {
expect(result.stylelint.disabledRanges).toEqual({ all: [] });
Expand Down Expand Up @@ -794,6 +796,29 @@ it('SCSS // disable comment (with // comment after blank line)', () => {
});
});

it('SCSS // disable comment (with // comment immediately after)', () => {
const scssSource = `a {
// stylelint-disable declaration-no-important
// Unrelated
color: pink !important;
}`;

return postcss()
.use(assignDisabledRanges)
.process(scssSource, { syntax: scss, from: undefined })
.then((result) => {
expect(result.stylelint.disabledRanges).toEqual({
all: [],
'declaration-no-important': [
{
start: 2,
strictStart: true,
},
],
});
});
});

it('SCSS /* disable comment (with // comment after blank line)', () => {
const scssSource = `a {
/* stylelint-disable declaration-no-important */
Expand All @@ -818,6 +843,122 @@ it('SCSS /* disable comment (with // comment after blank line)', () => {
});
});

it('SCSS // disable comment (with // comment immediately before)', () => {
const scssSource = `a {
// Unrelated
// stylelint-disable declaration-no-important
color: pink !important;
}`;

return postcss()
.use(assignDisabledRanges)
.process(scssSource, { syntax: scss, from: undefined })
.then((result) => {
expect(result.stylelint.disabledRanges).toEqual({
all: [],
'declaration-no-important': [
{
start: 3,
strictStart: true,
},
],
});
});
});

it('SCSS two adjacent // disable comments ', () => {
const scssSource = `a {
// stylelint-disable declaration-no-important
// stylelint-disable foo-bar
color: pink !important;
}`;

return postcss()
.use(assignDisabledRanges)
.process(scssSource, { syntax: scss, from: undefined })
.then((result) => {
expect(result.stylelint.disabledRanges).toEqual({
all: [],
'declaration-no-important': [
{
start: 2,
strictStart: true,
},
],
'foo-bar': [
{
start: 3,
strictStart: true,
},
],
});
});
});

it('SCSS two adjacent // disable comments with multi-line descriptions ', () => {
const scssSource = `a {
// stylelint-disable declaration-no-important --
// Description 1
// stylelint-disable foo-bar
// --
// Description 2
color: pink !important;
}`;

return postcss()
.use(assignDisabledRanges)
.process(scssSource, { syntax: scss, from: undefined })
.then((result) => {
expect(result.stylelint.disabledRanges).toEqual({
all: [],
'declaration-no-important': [
{
start: 2,
strictStart: true,
description: 'Description 1',
},
],
'foo-bar': [
{
start: 4,
strictStart: true,
description: 'Description 2',
},
],
});
});
});

it('SCSS two // disable comments with an unrelated comment between them', () => {
const scssSource = `a {
// stylelint-disable declaration-no-important
// Unrelated
// stylelint-disable foo-bar
color: pink !important;
}`;

return postcss()
.use(assignDisabledRanges)
.process(scssSource, { syntax: scss, from: undefined })
.then((result) => {
expect(result.stylelint.disabledRanges).toEqual({
all: [],
'declaration-no-important': [
{
start: 2,
strictStart: true,
},
],
'foo-bar': [
{
start: 4,
strictStart: true,
},
],
});
});
});

it('Less // line-disabling comment (with description)', () => {
const lessSource = `a {
color: pink !important; // stylelint-disable-line declaration-no-important -- Description
Expand Down Expand Up @@ -871,9 +1012,12 @@ it('Less // disable next-line comment (with multi-line description)', () => {

function expectDisableRanges(result, expected) {
const actual = result.stylelint.disabledRanges;

expect(Object.keys(actual)).toEqual(Object.keys(expected));

for (const [name, expectedRanges] of Object.entries(expected)) {
const actualRanges = actual[name];

expect(actualRanges).toHaveLength(expectedRanges.length);

for (let i = 0; i < expectedRanges.length; i++) {
Expand All @@ -884,6 +1028,7 @@ function expectDisableRanges(result, expected) {

function expectDisableRange(actual, expected) {
const actualMutable = _.cloneDeep(actual);

delete actualMutable.comment;
expect(actualMutable).toEqual(expected);
}
Expand Down
4 changes: 0 additions & 4 deletions lib/__tests__/invalidScopeDisables.test.js
Expand Up @@ -9,10 +9,6 @@ function fixture(name) {
return replaceBackslashes(path.join(__dirname, './fixtures/disableOptions', name));
}

function source(name) {
return path.join(__dirname, './fixtures/disableOptions', name);
}

it('invalidScopeDisables simple case', () => {
const config = {
rules: {
Expand Down
65 changes: 45 additions & 20 deletions lib/assignDisabledRanges.js
Expand Up @@ -68,35 +68,53 @@ module.exports = function (root, result) {
if (inlineEnd) {
// Ignore comments already processed by grouping with a previous one.
if (inlineEnd === comment) inlineEnd = null;
} else if (isInlineComment(comment)) {
const fullComment = comment.clone();
let next = comment.next();
let lastLine = (comment.source && comment.source.end && comment.source.end.line) || 0;

while (next && next.type === 'comment') {
/** @type {PostcssComment} */
const current = next;
return;
}

if (!isInlineComment(current)) break;
const next = comment.next();

// If any of these conditions are not met, do not merge comments.
if (
!(
isInlineComment(comment) &&
isStylelintCommand(comment) &&
next &&
next.type === 'comment' &&
(comment.text.includes('--') || next.text.startsWith('--'))
)
) {
checkComment(comment);

const currentLine = (current.source && current.source.end && current.source.end.line) || 0;
return;
}

if (lastLine + 1 !== currentLine) break;
let lastLine = (comment.source && comment.source.end && comment.source.end.line) || 0;
const fullComment = comment.clone();

fullComment.text += `\n${current.text}`;
/** @type {PostcssComment} */
let current = next;

if (fullComment.source && current.source) {
fullComment.source.end = current.source.end;
}
while (isInlineComment(current) && !isStylelintCommand(current)) {
const currentLine = (current.source && current.source.end && current.source.end.line) || 0;

if (lastLine + 1 !== currentLine) break;

inlineEnd = current;
next = current.next();
lastLine = currentLine;
fullComment.text += `\n${current.text}`;

if (fullComment.source && current.source) {
fullComment.source.end = current.source.end;
}
checkComment(fullComment);
} else {
checkComment(comment);

inlineEnd = current;
const next = current.next();

if (!next || next.type !== 'comment') break;

current = next;
lastLine = currentLine;
}
checkComment(fullComment);
});

return result;
Expand All @@ -110,6 +128,13 @@ module.exports = function (root, result) {
return comment.inline || comment.raws.inline;
}

/**
* @param {PostcssComment} comment
*/
function isStylelintCommand(comment) {
return comment.text.startsWith(disableCommand) || comment.text.startsWith(enableCommand);
}

/**
* @param {PostcssComment} comment
*/
Expand Down

0 comments on commit 2c392c6

Please sign in to comment.