Skip to content

Commit

Permalink
feat: add version as a setting (mysticatea#70)
Browse files Browse the repository at this point in the history
* feat: add version as a setting

* test: check settings

* docs

* docs: mention shareable configs

* style: lintfix
  • Loading branch information
privatenumber authored Dec 5, 2022
1 parent ed988f9 commit 273b937
Show file tree
Hide file tree
Showing 13 changed files with 274 additions and 45 deletions.
42 changes: 36 additions & 6 deletions docs/rules/no-unsupported-features/es-builtins.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,16 @@ See also [TC39 finished proposals](https://github.com/tc39/proposals/blob/master

### Configured Node.js version range

This rule reads the [engines] field of `package.json` to detect which Node.js versions your module is supporting.
This rule gets the supported Node.js version range from the following, falling back to the next if unspecified:

I recommend the use of the [engines] field because it's the official way that indicates which Node.js versions your module is supporting.
For example of `package.json`:
1. Rule configuration `version`
2. ESLint [shared setting](http://eslint.org/docs/user-guide/configuring.html#adding-shared-settings) `node.version`
3. `package.json` [`engines`] field
4. `>=8.0.0`

The default version is `8.0.0` because it's the minimum version the community is maintaining (see also [Node.js Release Working Group](https://github.com/nodejs/Release#readme)).

For Node.js packages, using the [`engines`] field is recommended because it's the official way to indicate support:

```json
{
Expand All @@ -34,7 +40,7 @@ For example of `package.json`:
}
```

If you omit the [engines] field, this rule chooses `>=8.0.0` as the configured Node.js version since `8` is the minimum version the community is maintaining (see also [Node.js Release Working Group](https://github.com/nodejs/Release#readme)).
For [Shareable Configs](https://eslint.org/docs/latest/developer-guide/shareable-configs) or packages with a different development environment (e.g. pre-compiled, web package, etc.), you can configure ESLint with `settings.node.version` to specify support.

### Options

Expand All @@ -49,7 +55,7 @@ If you omit the [engines] field, this rule chooses `>=8.0.0` as the configured N

#### version

As mentioned above, this rule reads the [engines] field of `package.json`.
As mentioned above, this rule reads the [`engines`] field of `package.json`.
But, you can overwrite the version by `version` option.

The `version` option accepts [the valid version range of `node-semver`](https://github.com/npm/node-semver#range-grammar).
Expand Down Expand Up @@ -140,6 +146,30 @@ The `"ignores"` option accepts an array of the following strings.

</details>

### Shared Settings

The following options can be set by [shared settings](http://eslint.org/docs/user-guide/configuring.html#adding-shared-settings).
Several rules have the same option, but we can set this option at once.

- `version`

For Example:

```json
{
"settings": {
"node": {
"version": ">=8.0.0",
}
},
"rules": {
"n/no-unsupported-features/es-builtins": ["error", {
"ignores": []
}]
}
}
```

### Known limitations

This rule cannot find non-static things.
Expand All @@ -150,7 +180,7 @@ For example:
- New `options` properties of function parameters.
- New events.

[engines]: https://docs.npmjs.com/files/package.json#engines
[`engines`]: https://docs.npmjs.com/files/package.json#engines

## 🔎 Implementation

Expand Down
42 changes: 36 additions & 6 deletions docs/rules/no-unsupported-features/es-syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,16 @@ For example, set `2020` to `parserOptions.ecmaVersion`.

### Configured Node.js version range

This rule reads the [engines] field of `package.json` to detect which Node.js versions your module is supporting.
This rule gets the supported Node.js version range from the following, falling back to the next if unspecified:

I recommend the use of the [engines] field because it's the official way that indicates which Node.js versions your module is supporting.
For example of `package.json`:
1. Rule configuration `version`
2. ESLint [shared setting](http://eslint.org/docs/user-guide/configuring.html#adding-shared-settings) `node.version`
3. `package.json` [`engines`] field
4. `>=8.0.0`

The default version is `8.0.0` because it's the minimum version the community is maintaining (see also [Node.js Release Working Group](https://github.com/nodejs/Release#readme)).

For Node.js packages, using the [`engines`] field is recommended because it's the official way to indicate support:

```json
{
Expand All @@ -37,7 +43,7 @@ For example of `package.json`:
}
```

If you omit the [engines] field, this rule chooses `>=8.0.0` as the configured Node.js version since `8` is the minimum version the community is maintaining (see also [Node.js Release Working Group](https://github.com/nodejs/Release#readme)).
For [Shareable Configs](https://eslint.org/docs/latest/developer-guide/shareable-configs) or packages with a different development environment (e.g. pre-compiled, web package, etc.), you can configure ESLint with `settings.node.version` to specify support.

### Options

Expand All @@ -52,7 +58,7 @@ If you omit the [engines] field, this rule chooses `>=8.0.0` as the configured N

#### version

As mentioned above, this rule reads the [engines] field of `package.json`.
As mentioned above, this rule reads the [`engines`] field of `package.json`.
But, you can overwrite the version by `version` option.

The `version` option accepts [the valid version range of `node-semver`](https://github.com/npm/node-semver#range-grammar).
Expand Down Expand Up @@ -123,7 +129,31 @@ The `"ignores"` option accepts an array of the following strings.

</details>

[engines]: https://docs.npmjs.com/files/package.json#engines
[`engines`]: https://docs.npmjs.com/files/package.json#engines

### Shared Settings

The following options can be set by [shared settings](http://eslint.org/docs/user-guide/configuring.html#adding-shared-settings).
Several rules have the same option, but we can set this option at once.

- `version`

For Example:

```json
{
"settings": {
"node": {
"version": ">=8.0.0",
}
},
"rules": {
"n/no-unsupported-features/es-syntax": ["error", {
"ignores": []
}]
}
}
```

## 🔎 Implementation

Expand Down
42 changes: 36 additions & 6 deletions docs/rules/no-unsupported-features/node-builtins.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,16 @@ This rule reports APIs of Node.js built-in APIs on the basis of [Node.js v13.2.0

### Configured Node.js version range

This rule reads the [engines] field of `package.json` to detect which Node.js versions your module is supporting.
This rule gets the supported Node.js version range from the following, falling back to the next if unspecified:

I recommend the use of the [engines] field because it's the official way that indicates which Node.js versions your module is supporting.
For example of `package.json`:
1. Rule configuration `version`
2. ESLint [shared setting](http://eslint.org/docs/user-guide/configuring.html#adding-shared-settings) `node.version`
3. `package.json` [`engines`] field
4. `>=8.0.0`

The default version is `8.0.0` because it's the minimum version the community is maintaining (see also [Node.js Release Working Group](https://github.com/nodejs/Release#readme)).

For Node.js packages, using the [`engines`] field is recommended because it's the official way to indicate support:

```json
{
Expand All @@ -31,7 +37,7 @@ For example of `package.json`:
}
```

If you omit the [engines] field, this rule chooses `>=8.0.0` as the configured Node.js version since `8` is the minimum version the community is maintaining (see also [Node.js Release Working Group](https://github.com/nodejs/Release#readme)).
For [Shareable Configs](https://eslint.org/docs/latest/developer-guide/shareable-configs) or packages with a different development environment (e.g. pre-compiled, web package, etc.), you can configure ESLint with `settings.node.version` to specify support.

### Options

Expand All @@ -46,7 +52,7 @@ If you omit the [engines] field, this rule chooses `>=8.0.0` as the configured N

#### version

As mentioned above, this rule reads the [engines] field of `package.json`.
As mentioned above, this rule reads the [`engines`] field of `package.json`.
But, you can overwrite the version by `version` option.

The `version` option accepts [the valid version range of `node-semver`](https://github.com/npm/node-semver#range-grammar).
Expand Down Expand Up @@ -324,6 +330,30 @@ The `"ignores"` option accepts an array of the following strings.

</details>

### Shared Settings

The following options can be set by [shared settings](http://eslint.org/docs/user-guide/configuring.html#adding-shared-settings).
Several rules have the same option, but we can set this option at once.

- `version`

For Example:

```json
{
"settings": {
"node": {
"version": ">=8.0.0",
}
},
"rules": {
"n/no-unsupported-features/node-builtins": ["error", {
"ignores": []
}]
}
}
```

### Known limitations

This rule cannot find non-static things.
Expand All @@ -334,7 +364,7 @@ For example:
- New `options` properties of function parameters.
- New events.

[engines]: https://docs.npmjs.com/files/package.json#engines
[`engines`]: https://docs.npmjs.com/files/package.json#engines

## 🔎 Implementation

Expand Down
12 changes: 5 additions & 7 deletions lib/rules/no-deprecated-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -671,8 +671,7 @@ function toName(type, path) {
*/
function parseOptions(context) {
const raw = context.options[0] || {}
const filePath = context.getFilename()
const version = getConfiguredNodeVersion(raw.version, filePath)
const version = getConfiguredNodeVersion(context)
const ignoredModuleItems = new Set(raw.ignoreModuleItems || [])
const ignoredGlobalItems = new Set(raw.ignoreGlobalItems || [])

Expand All @@ -693,9 +692,7 @@ module.exports = {
{
type: "object",
properties: {
version: {
type: "string",
},
version: getConfiguredNodeVersion.schema,
ignoreModuleItems: {
type: "array",
items: {
Expand All @@ -720,8 +717,9 @@ module.exports = {
},
],
messages: {
"deprecated": "{{name}} was deprecated since v{{version}}{{replace}}."
}
deprecated:
"{{name}} was deprecated since v{{version}}{{replace}}.",
},
},
create(context) {
const { ignoredModuleItems, ignoredGlobalItems, version } =
Expand Down
5 changes: 2 additions & 3 deletions lib/rules/no-unsupported-features/es-builtins.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const {
messages,
} = require("../../util/check-unsupported-builtins")
const enumeratePropertyNames = require("../../util/enumerate-property-names")
const getConfiguredNodeVersion = require("../../util/get-configured-node-version")

const trackMap = {
globals: {
Expand Down Expand Up @@ -152,9 +153,7 @@ module.exports = {
{
type: "object",
properties: {
version: {
type: "string",
},
version: getConfiguredNodeVersion.schema,
ignores: {
type: "array",
items: {
Expand Down
7 changes: 2 additions & 5 deletions lib/rules/no-unsupported-features/es-syntax.js
Original file line number Diff line number Diff line change
Expand Up @@ -412,8 +412,7 @@ const keywords = Object.keys(features)
*/
function parseOptions(context) {
const raw = context.options[0] || {}
const filePath = context.getFilename()
const version = getConfiguredNodeVersion(raw.version, filePath)
const version = getConfiguredNodeVersion(context)
const ignores = new Set(raw.ignores || [])

return Object.freeze({ version, ignores })
Expand Down Expand Up @@ -534,9 +533,7 @@ module.exports = {
{
type: "object",
properties: {
version: {
type: "string",
},
version: getConfiguredNodeVersion.schema,
ignores: {
type: "array",
items: {
Expand Down
7 changes: 3 additions & 4 deletions lib/rules/no-unsupported-features/node-builtins.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const {
messages,
} = require("../../util/check-unsupported-builtins")
const enumeratePropertyNames = require("../../util/enumerate-property-names")
const getConfiguredNodeVersion = require("../../util/get-configured-node-version")

const trackMap = {
globals: {
Expand Down Expand Up @@ -263,7 +264,7 @@ const trackMap = {
},
},
release: { [READ]: { supported: "3.0.0" } },
report: { [READ]: { supported: "14.0.0", experimental: "11.8.0"} },
report: { [READ]: { supported: "14.0.0", experimental: "11.8.0" } },
resourceUsage: { [READ]: { supported: "12.6.0" } },
setegid: { [READ]: { supported: "2.0.0" } },
seteuid: { [READ]: { supported: "2.0.0" } },
Expand Down Expand Up @@ -384,9 +385,7 @@ module.exports = {
{
type: "object",
properties: {
version: {
type: "string",
},
version: getConfiguredNodeVersion.schema,
ignores: {
type: "array",
items: {
Expand Down
3 changes: 1 addition & 2 deletions lib/util/check-unsupported-builtins.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ const getSemverRange = require("./get-semver-range")
*/
function parseOptions(context) {
const raw = context.options[0] || {}
const filePath = context.getFilename()
const version = getConfiguredNodeVersion(raw.version, filePath)
const version = getConfiguredNodeVersion(context)
const ignores = new Set(raw.ignores || [])

return Object.freeze({ version, ignores })
Expand Down
26 changes: 24 additions & 2 deletions lib/util/get-configured-node-version.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,19 @@ const { Range } = require("semver") //eslint-disable-line no-unused-vars
const getPackageJson = require("./get-package-json")
const getSemverRange = require("./get-semver-range")

/**
* Gets `version` property from a given option object.
*
* @param {object|undefined} option - An option object to get.
* @returns {string[]|null} The `allowModules` value, or `null`.
*/
function get(option) {
if (option && option.version) {
return option.version
}
return null
}

/**
* Get the `engines.node` field of package.json.
* @param {string} filename The path to the current linting file.
Expand All @@ -30,10 +43,19 @@ function getEnginesNode(filename) {
* This will be used to look package.json up if `version` is not a valid version range.
* @returns {Range} The configured version range.
*/
module.exports = function getConfiguredNodeVersion(version, filename) {
module.exports = function getConfiguredNodeVersion(context) {
const version =
get(context.options && context.options[0]) ||
get(context.settings && (context.settings.n || context.settings.node))
const filePath = context.getFilename()

return (
getSemverRange(version) ||
getEnginesNode(filename) ||
getEnginesNode(filePath) ||
getSemverRange(">=8.0.0")
)
}

module.exports.schema = {
type: "string",
}
Loading

0 comments on commit 273b937

Please sign in to comment.