Skip to content

Commit

Permalink
Add support autofix with checkAgainstRule (#6466)
Browse files Browse the repository at this point in the history
Co-authored-by: Masafumi Koba <473530+ybiquitous@users.noreply.github.com>
  • Loading branch information
aaronccasanova and ybiquitous committed Nov 11, 2022
1 parent b54083c commit 11b3c1e
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 10 deletions.
5 changes: 5 additions & 0 deletions .changeset/tricky-wolves-collect.md
@@ -0,0 +1,5 @@
---
"stylelint": minor
---

Added: support autofix with `checkAgainstRule`
6 changes: 4 additions & 2 deletions docs/developer-guide/plugins.md
Expand Up @@ -240,6 +240,7 @@ It accepts an options object and a callback that is invoked with warnings from t
- `ruleSettings`: settings for the rule you are invoking
- `root`: the root node to run this rule against
- `result?`: the PostCSS result for resolving and invoking custom rules
- `context?`: the [context](rules.md#add-autofix) for the rule you are invoking

Use the warning to create a _new_ warning _from your plugin rule_ that you report with `stylelint.utils.report`.

Expand All @@ -250,7 +251,7 @@ const allowableAtRules = [
/* .. */
];

function myPluginRule(primaryOption, secondaryOptionObject) {
function myPluginRule(primaryOption, secondaryOptionObject, ruleContext) {
return (postcssRoot, postcssResult) => {
const defaultedOptions = Object.assign({}, secondaryOptionObject, {
ignoreAtRules: allowableAtRules.concat(options.ignoreAtRules || [])
Expand All @@ -261,7 +262,8 @@ function myPluginRule(primaryOption, secondaryOptionObject) {
ruleName: "at-rule-no-unknown",
ruleSettings: [primaryOption, defaultedOptions],
root: postcssRoot,
result: postcssResult
result: postcssResult,
context: ruleContext
},
(warning) => {
stylelint.utils.report({
Expand Down
20 changes: 20 additions & 0 deletions lib/utils/__tests__/checkAgainstRule.test.js
Expand Up @@ -87,6 +87,26 @@ describe('checkAgainstRule', () => {
expect(warnings[0].column).toBe(1);
});

it('outputs fixed code when provided a context object', () => {
const root = postcss.parse(' a { color: red; }');
const context = { fix: true };

const warnings = [];

checkAgainstRule(
{
ruleName: 'indentation',
ruleSettings: 2,
root,
context,
},
(warning) => warnings.push(warning),
);

expect(warnings).toHaveLength(0);
expect(root.toString()).toBe('a { color: red; }');
});

it('checks against custom rule (passing)', () => {
const root = postcss.parse('.not-empty {}');

Expand Down
4 changes: 2 additions & 2 deletions lib/utils/checkAgainstRule.js
Expand Up @@ -16,7 +16,7 @@ function checkAgainstRule(options, callback) {

if (!callback) throw new Error('Expected a callback function');

const { ruleName, ruleSettings, root, result } = options;
const { ruleName, ruleSettings, root, result, context = {} } = options;

if (!ruleName) throw new Error('Expected a "ruleName" option');

Expand All @@ -37,7 +37,7 @@ function checkAgainstRule(options, callback) {
// @ts-expect-error - this error should not occur with PostCSS 8
const tmpPostcssResult = new Result();

rule(settings[0], /** @type {Object} */ (settings[1]), {})(root, tmpPostcssResult);
rule(settings[0], /** @type {Object} */ (settings[1]), context)(root, tmpPostcssResult);

for (const warning of tmpPostcssResult.warnings()) callback(warning);
}
Expand Down
18 changes: 12 additions & 6 deletions types/stylelint/index.d.ts
Expand Up @@ -148,11 +148,6 @@ declare module 'stylelint' {

export type CustomSyntax = string | PostCSS.Syntax;

export type PluginContext = {
fix?: boolean | undefined;
newline?: string | undefined;
};

// Note: With strict function types enabled, function signatures are checked contravariantly.
// This means that it would not be possible for rule authors to narrow the message function
// parameters to e.g. just `string`. Declaring the type for rule message functions through
Expand Down Expand Up @@ -180,10 +175,20 @@ declare module 'stylelint' {
optional?: boolean;
};

export type RuleContext = {
fix?: boolean | undefined;
newline?: string | undefined;
};

/**
* @deprecated Use `RuleContext` instead.
*/
export type PluginContext = RuleContext;

export type RuleBase<P = any, S = any> = (
primaryOption: P,
secondaryOptions: Record<string, S>,
context: PluginContext,
context: RuleContext,
) => (root: PostCSS.Root, result: PostcssResult) => Promise<void> | void;

export type RuleMeta = {
Expand Down Expand Up @@ -518,6 +523,7 @@ declare module 'stylelint' {
ruleSettings: ConfigRuleSettings<T, O>;
root: PostCSS.Root;
result?: PostcssResult;
context?: RuleContext;
},
callback: (warning: PostCSS.Warning) => void,
) => void;
Expand Down

0 comments on commit 11b3c1e

Please sign in to comment.