Skip to content

Commit

Permalink
Add syntax object acceptance to customSyntax option (#4839)
Browse files Browse the repository at this point in the history
  • Loading branch information
m-allanson committed Jul 6, 2020
1 parent 2ad2a24 commit 03a0cea
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 20 deletions.
8 changes: 8 additions & 0 deletions docs/user-guide/usage/cli.md
Expand Up @@ -106,6 +106,14 @@ Using `bar/mySpecialConfig.json` as config to lint all `.css` files in the `foo`
stylelint "foo/**/*.css" --config bar/mySpecialConfig.json
```

### Example H - using a custom syntax

Recursively linting all `.css` files in the `foo` directory using a custom syntax:

```shell
stylelint "foo/**/*.css" --customSyntax path/to/my-custom-syntax.js
```

## Exit codes

The CLI can exit the process with the following exit codes:
Expand Down
25 changes: 25 additions & 0 deletions docs/user-guide/usage/node-api.md
Expand Up @@ -150,3 +150,28 @@ stylelint
/* .. */
});
```

### Example E

Using a custom syntax:

```js
stylelint
.lint({
config: myConfig,
files: "all/my/stylesheets/*.css",
customSyntax: {
parse: (css, opts) => {
/* .. */
},
stringify: (root, builder) => {
/* .. */
}
}
})
.then(function () {
/* .. */
});
```

Note that the customSyntax option also accepts a string. [Refer to the options documentation for details](./options.md).
10 changes: 7 additions & 3 deletions docs/user-guide/usage/options.md
Expand Up @@ -101,17 +101,21 @@ Specify a syntax. Options:
- `scss`
- `sugarss`

If you do not specify a syntax, stylelint automatically infer the syntaxes.
If you do not specify a syntax, stylelint will automatically infer the syntaxes.

Only use this option if you want to force a specific syntax.

## `customSyntax`

CLI flag: `--custom-syntax`

Module name or path to a JS file exporting a [PostCSS-compatible syntax](https://github.com/postcss/postcss#syntaxes).
Specify a custom syntax to use on your code. Use this option if you want to force a specific syntax that's not already built into stylelint.

Note, however, that stylelint can provide no guarantee that core rules work with syntaxes other than the defaults listed for the `syntax` option above.
This option should be a string that resolves to a JS module that exports a [PostCSS-compatible syntax](https://github.com/postcss/postcss#syntaxes). The string can be a module name (like `my-module`) or a path to a JS file (like `path/to/my-module.js`).

Using the Node.js API, the `customSyntax` option can also accept a [Syntax object](https://github.com/postcss/postcss/blob/abfaa7122a0f480bc5be0905df3c24a6a51a82d9/lib/postcss.d.ts#L223-L232). Stylelint treats the `parse` property as a required value.

Note that stylelint can provide no guarantee that core rules work with syntaxes other than the defaults listed for the `syntax` option above.

## `disableDefaultIgnores`

Expand Down
4 changes: 3 additions & 1 deletion lib/__tests__/standalone.test.js
Expand Up @@ -243,7 +243,9 @@ it('unknown custom syntax option', () => {
throw new Error('should not have succeeded');
})
.catch((err) => {
expect(err.message).toBe('Cannot resolve custom syntax module unknown-module');
expect(err.message).toBe(
'Cannot resolve custom syntax module unknown-module. Check that module unknown-module is available and spelled correctly.',
);
});
});

Expand Down
46 changes: 32 additions & 14 deletions lib/getPostcssResult.js
Expand Up @@ -117,24 +117,42 @@ module.exports = function (stylelint, options = {}) {
function getCustomSyntax(customSyntax) {
let resolved;

try {
resolved = require(customSyntax);
} catch (error) {
throw new Error(`Cannot resolve custom syntax module ${customSyntax}`);
if (typeof customSyntax === 'string') {
try {
resolved = require(customSyntax);
} catch (error) {
throw new Error(
`Cannot resolve custom syntax module ${customSyntax}. Check that module ${customSyntax} is available and spelled correctly.`,
);
}

/*
* PostCSS allows for syntaxes that only contain a parser, however,
* it then expects the syntax to be set as the `parse` option.
*/
if (!resolved.parse) {
resolved = {
parse: resolved,
stringify: postcss.stringify,
};
}

return resolved;
}

/*
* PostCSS allows for syntaxes that only contain a parser, however,
* it then expects the syntax to be set as the `parse` option.
*/
if (!resolved.parse) {
resolved = {
parse: resolved,
stringify: postcss.stringify,
};
if (typeof customSyntax === 'object') {
if (typeof customSyntax.parse === 'function') {
resolved = { ...customSyntax };
} else {
throw new Error(
`An object provided to the "customSyntax" option must have a "parse" property. Ensure the "parse" property exists and its value is a function.`,
);
}

return resolved;
}

return resolved;
throw new Error(`Custom syntax must be a string or a Syntax object`);
}

/**
Expand Down
4 changes: 2 additions & 2 deletions types/stylelint/index.d.ts
@@ -1,5 +1,5 @@
declare module 'stylelint' {
import { Result, ResultMessage, WarningOptions, Warning } from 'postcss';
import { Result, ResultMessage, Syntax, WarningOptions, Warning } from 'postcss';

export type StylelintConfigExtends = string | Array<string>;
export type StylelintConfigPlugins = string | Array<string>;
Expand Down Expand Up @@ -90,7 +90,7 @@ declare module 'stylelint' {

export type FormatterIdentifier = 'compact' | 'json' | 'string' | 'unix' | 'verbose' | Formatter;

export type CustomSyntax = string;
export type CustomSyntax = string | Syntax;

export type StylelintOptions = {
config?: StylelintConfig;
Expand Down

0 comments on commit 03a0cea

Please sign in to comment.