eslint-plugin-boundaries 3.3.0 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -228,6 +228,37 @@ Files or dependencies matching these [`micromatch` patterns](https://github.com/
228
228
 
229
229
  > Note: The `boundaries/include` option has preference over `boundaries/ignore`. If you define `boundaries/include`, use `boundaries/ignore` to ignore subsets of included files.
230
230
 
231
+ #### __`boundaries/root-path`__
232
+
233
+ Use this setting only if you are facing issues with the plugin when executing the lint command from a different path than the project root.
234
+
235
+ <details>
236
+ <summary>How to define the root path of the project</summary>
237
+
238
+ By default, the plugin uses the current working directory (`process.cwd()`) as root path of the project. This path is used as the base path when resolving file matchers from rules and `boundaries/elements` settings. This is specially important when using the `basePattern` option or the `full` mode in the `boundaries/elements` setting. This may produce unexpected results [when the lint command is executed from a different path than the project root](https://github.com/javierbrea/eslint-plugin-boundaries/issues/296). To fix this, you can define a different root path using this option.
239
+
240
+ For example, supposing that the `.eslintrc.js` file is located in the project root, you could define the root path as in:
241
+
242
+ ```js
243
+ {
244
+ settings: {
245
+ "boundaries/root-path": path.resolve(__dirname)
246
+ }
247
+ }
248
+ ```
249
+
250
+ Note that the path should be absolute and resolved before passing it to the plugin. Otherwise, it will be resolved using the current working directory, and the problem will persist. In case you are defining the configuration in a `.eslintrc.(yml|json)` file, and you don't want to hardcode an absolute path, you can use the next environment variable to define the root path when executing the lint command:
251
+
252
+ ```bash
253
+ ESLINT_PLUGIN_BOUNDARIES_ROOT_PATH=../../project-root npm run lint
254
+ ```
255
+
256
+ You can also provide an absolute path in the environment variable, but it may be more useful to use a relative path to the project root. Remember that it will be resolved from the path where the lint command is executed.
257
+
258
+ </details>
259
+
260
+
261
+
231
262
  ### Predefined configurations
232
263
 
233
264
  This plugin is distributed with two different predefined configurations: "recommended" and "strict".
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-boundaries",
3
- "version": "3.3.0",
3
+ "version": "3.4.0",
4
4
  "description": "Eslint plugin checking architecture boundaries between elements",
5
5
  "keywords": [
6
6
  "eslint",
@@ -1,5 +1,7 @@
1
1
  const PLUGIN_NAME = "boundaries";
2
+ const PLUGIN_ENV_VARS_PREFIX = "ESLINT_PLUGIN_BOUNDARIES";
2
3
 
3
4
  module.exports = {
4
5
  PLUGIN_NAME,
6
+ PLUGIN_ENV_VARS_PREFIX,
5
7
  };
@@ -1,4 +1,4 @@
1
- const { PLUGIN_NAME } = require("./plugin");
1
+ const { PLUGIN_NAME, PLUGIN_ENV_VARS_PREFIX } = require("./plugin");
2
2
 
3
3
  const {
4
4
  ELEMENT_TYPES,
@@ -15,6 +15,11 @@ module.exports = {
15
15
  ELEMENTS: `${PLUGIN_NAME}/elements`,
16
16
  IGNORE: `${PLUGIN_NAME}/ignore`,
17
17
  INCLUDE: `${PLUGIN_NAME}/include`,
18
+ ROOT_PATH: `${PLUGIN_NAME}/root-path`,
19
+
20
+ // env vars
21
+ DEBUG: `${PLUGIN_ENV_VARS_PREFIX}_DEBUG`,
22
+ ENV_ROOT_PATH: `${PLUGIN_ENV_VARS_PREFIX}_ROOT_PATH`,
18
23
 
19
24
  // rules
20
25
  RULE_ELEMENT_TYPES: `${PLUGIN_NAME}/${ELEMENT_TYPES}`,
@@ -3,7 +3,7 @@ const micromatch = require("micromatch");
3
3
  const resolve = require("eslint-module-utils/resolve").default;
4
4
 
5
5
  const { IGNORE, INCLUDE, VALID_MODES } = require("../constants/settings");
6
- const { getElements } = require("../helpers/settings");
6
+ const { getElements, getRootPath } = require("../helpers/settings");
7
7
  const { debugFileInfo } = require("../helpers/debug");
8
8
  const { isArray } = require("../helpers/utils");
9
9
 
@@ -184,9 +184,9 @@ function replacePathSlashes(absolutePath) {
184
184
  return absolutePath.replace(/\\/g, "/");
185
185
  }
186
186
 
187
- function projectPath(absolutePath) {
187
+ function projectPath(absolutePath, rootPath) {
188
188
  if (absolutePath) {
189
- return replacePathSlashes(absolutePath).replace(`${replacePathSlashes(process.cwd())}/`, "");
189
+ return replacePathSlashes(absolutePath).replace(`${replacePathSlashes(rootPath)}/`, "");
190
190
  }
191
191
  }
192
192
 
@@ -195,7 +195,7 @@ function externalModulePath(source, baseModuleValue) {
195
195
  }
196
196
 
197
197
  function importInfo(source, context) {
198
- const path = projectPath(resolve(source, context));
198
+ const path = projectPath(resolve(source, context), getRootPath(context.settings));
199
199
  const isExternalModule = isExternal(source, path);
200
200
  const resultCache = importsCache.load(isExternalModule ? source : path, context.settings);
201
201
  let elementCache;
@@ -237,7 +237,7 @@ function importInfo(source, context) {
237
237
  }
238
238
 
239
239
  function fileInfo(context) {
240
- const path = projectPath(context.getFilename());
240
+ const path = projectPath(context.getFilename(), getRootPath(context.settings));
241
241
  const resultCache = filesCache.load(path, context.settings);
242
242
  let elementCache;
243
243
  let result;
@@ -1,6 +1,7 @@
1
1
  const chalk = require("chalk");
2
2
 
3
3
  const { PLUGIN_NAME } = require("../constants/plugin");
4
+ const { isDebugModeEnabled } = require("./settings");
4
5
 
5
6
  const warns = [];
6
7
  const debuggedFiles = [];
@@ -13,12 +14,6 @@ function warn(message) {
13
14
  trace(message, "yellow");
14
15
  }
15
16
 
16
- function debug(message) {
17
- if (process.env.ESLINT_PLUGIN_BOUNDARIES_DEBUG) {
18
- trace(message, "grey");
19
- }
20
- }
21
-
22
17
  function success(message) {
23
18
  trace(message, "green");
24
19
  }
@@ -32,7 +27,7 @@ function warnOnce(message) {
32
27
 
33
28
  function debugFileInfo(fileInfo) {
34
29
  const fileInfoKey = fileInfo.path || fileInfo.source;
35
- if (process.env.ESLINT_PLUGIN_BOUNDARIES_DEBUG && !debuggedFiles.includes(fileInfoKey)) {
30
+ if (isDebugModeEnabled() && !debuggedFiles.includes(fileInfoKey)) {
36
31
  debuggedFiles.push(fileInfoKey);
37
32
  if (fileInfo.type) {
38
33
  success(`'${fileInfoKey}' is of type '${fileInfo.type}'`);
@@ -44,7 +39,6 @@ function debugFileInfo(fileInfo) {
44
39
  }
45
40
 
46
41
  module.exports = {
47
- debug,
48
42
  success,
49
43
  debugFileInfo,
50
44
  warnOnce,
@@ -1,5 +1,13 @@
1
- const { TYPES, ELEMENTS, VALID_MODES } = require("../constants/settings");
1
+ const {
2
+ TYPES,
3
+ ELEMENTS,
4
+ VALID_MODES,
5
+ ROOT_PATH,
6
+ ENV_ROOT_PATH,
7
+ DEBUG,
8
+ } = require("../constants/settings");
2
9
  const { isString } = require("./utils");
10
+ const { isAbsolute, resolve } = require("path");
3
11
 
4
12
  function isLegacyType(type) {
5
13
  return isString(type);
@@ -34,8 +42,24 @@ function getElementsTypeNames(settings) {
34
42
  return getElements(settings).map((element) => element.type);
35
43
  }
36
44
 
45
+ function getRootPath(settings) {
46
+ const rootPathUserSetting = process.env[ENV_ROOT_PATH] || settings[ROOT_PATH];
47
+ if (rootPathUserSetting) {
48
+ return isAbsolute(rootPathUserSetting)
49
+ ? rootPathUserSetting
50
+ : resolve(process.cwd(), rootPathUserSetting);
51
+ }
52
+ return process.cwd();
53
+ }
54
+
55
+ function isDebugModeEnabled() {
56
+ return process.env[DEBUG];
57
+ }
58
+
37
59
  module.exports = {
38
60
  isLegacyType,
39
61
  getElements,
40
62
  getElementsTypeNames,
63
+ isDebugModeEnabled,
64
+ getRootPath,
41
65
  };