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 11b6b83
Show file tree
Hide file tree
Showing 65 changed files with 598 additions and 252 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 included in the [`reportedDisables`](usage/node-api.md#reporteddisables) property to the returned data of Node.js API.

## `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 a [`descriptionlessDisables`](node-api.md#descriptionlessdisables) property to the returned data

## `codeFilename`

CLI flag: `--stdin-filename`
Expand Down
139 changes: 139 additions & 0 deletions lib/__tests__/disableRanges.test.js
Expand Up @@ -794,6 +794,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 +841,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
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
7 changes: 6 additions & 1 deletion lib/rules/at-rule-blacklist/__tests__/index.js
@@ -1,7 +1,7 @@
'use strict';

const standalone = require('../../../standalone');
const { messages, ruleName } = require('..');
const { messages, ruleName, meta } = require('..');

it('warns that the rule is deprecated', () => {
const config = {
Expand All @@ -25,6 +25,11 @@ it('warns that the rule is deprecated', () => {
});
});

it('also warns that the rule is deprecated via a meta', () => {
expect(meta).not.toBeUndefined();
expect(meta).toHaveProperty('deprecated', true);
});

testRule({
ruleName,

Expand Down
2 changes: 2 additions & 0 deletions lib/rules/at-rule-blacklist/index.js
Expand Up @@ -59,4 +59,6 @@ rule.primaryOptionArray = true;

rule.ruleName = ruleName;
rule.messages = messages;
rule.meta = { deprecated: true };

module.exports = rule;
7 changes: 6 additions & 1 deletion lib/rules/at-rule-property-requirelist/__tests__/index.js
@@ -1,7 +1,7 @@
'use strict';

const standalone = require('../../../standalone');
const { messages, ruleName } = require('..');
const { messages, ruleName, meta } = require('..');

it('warns that the rule is deprecated', () => {
const config = {
Expand All @@ -25,6 +25,11 @@ it('warns that the rule is deprecated', () => {
});
});

it('also warns that the rule is deprecated via a meta', () => {
expect(meta).not.toBeUndefined();
expect(meta).toHaveProperty('deprecated', true);
});

testRule({
ruleName,
config: {
Expand Down
1 change: 1 addition & 0 deletions lib/rules/at-rule-property-requirelist/index.js
Expand Up @@ -69,5 +69,6 @@ function rule(list) {

rule.ruleName = ruleName;
rule.messages = messages;
rule.meta = { deprecated: true };

module.exports = rule;

0 comments on commit 11b6b83

Please sign in to comment.