From 972a69cc293b7846294d8cf348b3e5bd538c6936 Mon Sep 17 00:00:00 2001 From: Nitin Kumar Date: Sat, 22 Apr 2023 20:19:42 +0530 Subject: [PATCH 1/5] feat: add `cwd` to rule context --- docs/src/extend/custom-rules.md | 3 +- docs/src/integrate/nodejs-api.md | 2 +- lib/linter/linter.js | 1 + tests/lib/linter/linter.js | 89 ++++++++++++++++++++++++++++++-- 4 files changed, 90 insertions(+), 5 deletions(-) diff --git a/docs/src/extend/custom-rules.md b/docs/src/extend/custom-rules.md index b416318a319..b7e2c280e94 100644 --- a/docs/src/extend/custom-rules.md +++ b/docs/src/extend/custom-rules.md @@ -134,7 +134,8 @@ The `context` object has the following properties: Additionally, the `context` object has the following methods: * `getAncestors()`: (**Deprecated:** Use `SourceCode#getAncestors(node)` instead.) Returns an array of the ancestors of the currently-traversed node, starting at the root of the AST and continuing through the direct parent of the current node. This array does not include the currently-traversed node itself. -* `getCwd()`: Returns the `cwd` option passed to the [Linter](../integrate/nodejs-api#linter). It is a path to a directory that should be considered the current working directory. +* `getCwd()`: (**Deprecated:** Use `Context#cwd` instead.) Returns the `cwd` option passed to the [Linter](../integrate/nodejs-api#linter). It is a path to a directory that should be considered the current working directory. +* `cwd`: Returns the `cwd` option passed to the [Linter](../integrate/nodejs-api#linter). It is a path to a directory that should be considered the current working directory. * `getDeclaredVariables(node)`: (**Deprecated:** Use `SourceCode#getDeclaredVariables(node)` instead.) Returns a list of [variables](./scope-manager-interface#variable-interface) declared by the given node. This information can be used to track references to variables. * If the node is a `VariableDeclaration`, all variables declared in the declaration are returned. * If the node is a `VariableDeclarator`, all variables declared in the declarator are returned. diff --git a/docs/src/integrate/nodejs-api.md b/docs/src/integrate/nodejs-api.md index de035ca731c..c552728e9ce 100644 --- a/docs/src/integrate/nodejs-api.md +++ b/docs/src/integrate/nodejs-api.md @@ -510,7 +510,7 @@ The `Linter` object does the actual evaluation of the JavaScript code. It doesn' The `Linter` is a constructor, and you can create a new instance by passing in the options you want to use. The available options are: -* `cwd` - Path to a directory that should be considered as the current working directory. It is accessible to rules by calling `context.getCwd()` (see [The Context Object](../extend/custom-rules#the-context-object)). If `cwd` is `undefined`, it will be normalized to `process.cwd()` if the global `process` object is defined (for example, in the Node.js runtime) , or `undefined` otherwise. +* `cwd` - Path to a directory that should be considered as the current working directory. It is accessible to rules by calling `context.getCwd()` or `context.cwd` (see [The Context Object](../extend/custom-rules#the-context-object)). If `cwd` is `undefined`, it will be normalized to `process.cwd()` if the global `process` object is defined (for example, in the Node.js runtime) , or `undefined` otherwise. For example: diff --git a/lib/linter/linter.js b/lib/linter/linter.js index 9573e7aefc2..27345e771fc 100644 --- a/lib/linter/linter.js +++ b/lib/linter/linter.js @@ -951,6 +951,7 @@ function runRules(sourceCode, configuredRules, ruleMapper, parserName, languageO getAncestors: () => sourceCode.getAncestors(currentNode), getDeclaredVariables: node => sourceCode.getDeclaredVariables(node), getCwd: () => cwd, + cwd, getFilename: () => filename, filename, getPhysicalFilename: () => physicalFilename || filename, diff --git a/tests/lib/linter/linter.js b/tests/lib/linter/linter.js index efb265d69f3..acdffb25fd0 100644 --- a/tests/lib/linter/linter.js +++ b/tests/lib/linter/linter.js @@ -3947,7 +3947,7 @@ var a = "test2"; linterWithOption.defineRule("checker", { create(context) { spy = sinon.spy(() => { - assert.strictEqual(context.getCwd(), cwd); + assert.strictEqual(context.cwd, cwd); }); return { Program: spy }; } @@ -3965,7 +3965,7 @@ var a = "test2"; create(context) { spy = sinon.spy(() => { - assert.strictEqual(context.getCwd(), process.cwd()); + assert.strictEqual(context.cwd, process.cwd()); }); return { Program: spy }; } @@ -3982,7 +3982,7 @@ var a = "test2"; create(context) { spy = sinon.spy(() => { - assert.strictEqual(context.getCwd(), process.cwd()); + assert.strictEqual(context.cwd, process.cwd()); }); return { Program: spy }; } @@ -11020,6 +11020,89 @@ describe("Linter with FlatConfigArray", () => { }); }); + describe("context.cwd", () => { + const code = "a;\nb;"; + const baseConfig = { rules: { "test/checker": "error" } }; + + it("should get cwd correctly in the context", () => { + const cwd = "cwd"; + const linterWithOption = new Linter({ cwd, configType: "flat" }); + let spy; + const config = { + plugins: { + test: { + rules: { + checker: { + create(context) { + spy = sinon.spy(() => { + assert.strictEqual(context.cwd, cwd); + }); + return { Program: spy }; + } + } + } + } + }, + ...baseConfig + }; + + linterWithOption.verify(code, config); + assert(spy && spy.calledOnce); + }); + + it("should assign process.cwd() to it if cwd is undefined", () => { + + const linterWithOption = new Linter({ configType: "flat" }); + let spy; + const config = { + plugins: { + test: { + rules: { + checker: { + create(context) { + + spy = sinon.spy(() => { + assert.strictEqual(context.cwd, process.cwd()); + }); + return { Program: spy }; + } + } + } + } + }, + ...baseConfig + }; + + linterWithOption.verify(code, config); + assert(spy && spy.calledOnce); + }); + + it("should assign process.cwd() to it if the option is undefined", () => { + let spy; + const config = { + plugins: { + test: { + rules: { + checker: { + create(context) { + + spy = sinon.spy(() => { + assert.strictEqual(context.cwd, process.cwd()); + }); + return { Program: spy }; + } + } + } + } + }, + ...baseConfig + }; + + linter.verify(code, config); + assert(spy && spy.calledOnce); + }); + }); + }); describe("Rule Severity", () => { From a559451cba67cf6829df8d23215b21a16e1e61e2 Mon Sep 17 00:00:00 2001 From: Nitin Kumar Date: Sat, 22 Apr 2023 20:23:35 +0530 Subject: [PATCH 2/5] docs: add more context.cwd references --- docs/src/integrate/nodejs-api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/integrate/nodejs-api.md b/docs/src/integrate/nodejs-api.md index c552728e9ce..b86d452f6ad 100644 --- a/docs/src/integrate/nodejs-api.md +++ b/docs/src/integrate/nodejs-api.md @@ -520,7 +520,7 @@ const linter1 = new Linter({ cwd: 'path/to/project' }); const linter2 = new Linter(); ``` -In this example, rules run on `linter1` will get `path/to/project` when calling `context.getCwd()`. +In this example, rules run on `linter1` will get `path/to/project` when calling `context.getCwd()` or `context.cwd`. Those run on `linter2` will get `process.cwd()` if the global `process` object is defined or `undefined` otherwise (e.g. on the browser ). ### Linter#verify From 91122da99f4c6705537f6de44b8c9e2024fd5fff Mon Sep 17 00:00:00 2001 From: Nitin Kumar Date: Thu, 27 Apr 2023 19:57:24 +0530 Subject: [PATCH 3/5] tests: add asertions for context.getCwd() --- docs/src/extend/custom-rules.md | 4 ++-- tests/lib/linter/linter.js | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/src/extend/custom-rules.md b/docs/src/extend/custom-rules.md index b7e2c280e94..d561651c0d3 100644 --- a/docs/src/extend/custom-rules.md +++ b/docs/src/extend/custom-rules.md @@ -125,6 +125,7 @@ The `context` object has the following properties: * `id`: (`string`) The rule ID. * `filename`: (`string`) The filename associated with the source. +* `cwd`: (`string`) The `cwd` option passed to the [Linter](../integrate/nodejs-api#linter). It is a path to a directory that should be considered the current working directory. * `options`: (`array`) An array of the [configured options](../use/configure/rules) for this rule. This array does not include the rule severity (see the [dedicated section](#accessing-options-passed-to-a-rule)). * `settings`: (`object`) The [shared settings](../use/configure/configuration-files#adding-shared-settings) from the configuration. * `parserPath`: (`string`) The name of the `parser` from the configuration. @@ -134,8 +135,7 @@ The `context` object has the following properties: Additionally, the `context` object has the following methods: * `getAncestors()`: (**Deprecated:** Use `SourceCode#getAncestors(node)` instead.) Returns an array of the ancestors of the currently-traversed node, starting at the root of the AST and continuing through the direct parent of the current node. This array does not include the currently-traversed node itself. -* `getCwd()`: (**Deprecated:** Use `Context#cwd` instead.) Returns the `cwd` option passed to the [Linter](../integrate/nodejs-api#linter). It is a path to a directory that should be considered the current working directory. -* `cwd`: Returns the `cwd` option passed to the [Linter](../integrate/nodejs-api#linter). It is a path to a directory that should be considered the current working directory. +* `getCwd()`: (**Deprecated:** Use `context.cwd` instead.) Returns the `cwd` option passed to the [Linter](../integrate/nodejs-api#linter). It is a path to a directory that should be considered the current working directory. * `getDeclaredVariables(node)`: (**Deprecated:** Use `SourceCode#getDeclaredVariables(node)` instead.) Returns a list of [variables](./scope-manager-interface#variable-interface) declared by the given node. This information can be used to track references to variables. * If the node is a `VariableDeclaration`, all variables declared in the declaration are returned. * If the node is a `VariableDeclarator`, all variables declared in the declarator are returned. diff --git a/tests/lib/linter/linter.js b/tests/lib/linter/linter.js index acdffb25fd0..e70761d3ea3 100644 --- a/tests/lib/linter/linter.js +++ b/tests/lib/linter/linter.js @@ -3965,6 +3965,7 @@ var a = "test2"; create(context) { spy = sinon.spy(() => { + assert.strictEqual(context.getCwd(), context.cwd); assert.strictEqual(context.cwd, process.cwd()); }); return { Program: spy }; @@ -3982,6 +3983,7 @@ var a = "test2"; create(context) { spy = sinon.spy(() => { + assert.strictEqual(context.getCwd(), context.cwd); assert.strictEqual(context.cwd, process.cwd()); }); return { Program: spy }; @@ -11062,6 +11064,7 @@ describe("Linter with FlatConfigArray", () => { create(context) { spy = sinon.spy(() => { + assert.strictEqual(context.getCwd(), context.cwd); assert.strictEqual(context.cwd, process.cwd()); }); return { Program: spy }; @@ -11087,6 +11090,7 @@ describe("Linter with FlatConfigArray", () => { create(context) { spy = sinon.spy(() => { + assert.strictEqual(context.getCwd(), context.cwd); assert.strictEqual(context.cwd, process.cwd()); }); return { Program: spy }; From 11a7e06d27ce50e78a8994afdca85d031bdd5fee Mon Sep 17 00:00:00 2001 From: Nitin Kumar Date: Fri, 28 Apr 2023 10:09:57 +0530 Subject: [PATCH 4/5] docs: apply suggestions from code review Co-authored-by: Francesco Trotta --- docs/src/integrate/nodejs-api.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/integrate/nodejs-api.md b/docs/src/integrate/nodejs-api.md index b86d452f6ad..853abdc57b8 100644 --- a/docs/src/integrate/nodejs-api.md +++ b/docs/src/integrate/nodejs-api.md @@ -510,7 +510,7 @@ The `Linter` object does the actual evaluation of the JavaScript code. It doesn' The `Linter` is a constructor, and you can create a new instance by passing in the options you want to use. The available options are: -* `cwd` - Path to a directory that should be considered as the current working directory. It is accessible to rules by calling `context.getCwd()` or `context.cwd` (see [The Context Object](../extend/custom-rules#the-context-object)). If `cwd` is `undefined`, it will be normalized to `process.cwd()` if the global `process` object is defined (for example, in the Node.js runtime) , or `undefined` otherwise. +* `cwd` - Path to a directory that should be considered as the current working directory. It is accessible to rules from `context.cwd` or by calling `context.getCwd()` (see [The Context Object](../extend/custom-rules#the-context-object)). If `cwd` is `undefined`, it will be normalized to `process.cwd()` if the global `process` object is defined (for example, in the Node.js runtime) , or `undefined` otherwise. For example: @@ -520,7 +520,7 @@ const linter1 = new Linter({ cwd: 'path/to/project' }); const linter2 = new Linter(); ``` -In this example, rules run on `linter1` will get `path/to/project` when calling `context.getCwd()` or `context.cwd`. +In this example, rules run on `linter1` will get `path/to/project` from `context.cwd` or when calling `context.getCwd()`. Those run on `linter2` will get `process.cwd()` if the global `process` object is defined or `undefined` otherwise (e.g. on the browser ). ### Linter#verify From 108e149fe69fe0d91e660d8798d68dc29826b2de Mon Sep 17 00:00:00 2001 From: Nitin Kumar Date: Sat, 29 Apr 2023 07:23:41 +0530 Subject: [PATCH 5/5] chore: update test assestion for context.getCwd() --- tests/lib/linter/linter.js | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/lib/linter/linter.js b/tests/lib/linter/linter.js index e70761d3ea3..a487eb23662 100644 --- a/tests/lib/linter/linter.js +++ b/tests/lib/linter/linter.js @@ -3947,6 +3947,7 @@ var a = "test2"; linterWithOption.defineRule("checker", { create(context) { spy = sinon.spy(() => { + assert.strictEqual(context.getCwd(), context.cwd); assert.strictEqual(context.cwd, cwd); }); return { Program: spy };