ilib-lint 2.0.0 → 2.0.1

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.
@@ -1,6 +1,32 @@
1
1
  Release Notes
2
2
  ============================
3
3
 
4
+ ### v2.0.1
5
+ - fixed loading of plugins
6
+ - if a plugin `ilib-lint-x` exists and a different package `x`
7
+ also exists that is unrelated to ilib-lint, and the config
8
+ says to load the plugin named simply `x`, it would first attempt
9
+ to load package `x`, succeed to load it, but then fail to
10
+ initialize it because `x` is not really an ilib-lint plugin.
11
+ - Another problem is that if this type of error occurred, it
12
+ would not attempt to load any other paths or plugins. This means
13
+ it would not load the perfectly valid plugin that is there
14
+ just because there was a conflicting package name.
15
+ - Additionally, if given a path directly to the plugin (absolute
16
+ or relative), it would not load that specific plugin and just
17
+ fail completely.
18
+ - Now, it:
19
+ - loads the specific plugin given a path to it
20
+ - if the plugin name is specified with the prefix like
21
+ `ilib-lint-x` it will attempt to load that package in various
22
+ locations until it finds one that works
23
+ - if the name is specified as simply `x`, it will attempt to
24
+ load the `ilib-lint-x` package first and only if it fails to
25
+ load or does not initialize properly will it fall back to
26
+ attempting to load the package just named just `x`
27
+ - updated dependencies
28
+ - fixed to set the formatter which designated from the command line option.
29
+
4
30
  ### v2.0.0
5
31
 
6
32
  - updated to use ilib-lint-common instead of i18nlint-common. (Same library, new name.)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ilib-lint",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "module": "./src/index.js",
5
5
  "type": "module",
6
6
  "bin": "./src/index.js",
@@ -61,24 +61,24 @@
61
61
  },
62
62
  "devDependencies": {
63
63
  "@tsconfig/node14": "^14.1.0",
64
- "@types/node": "^20.8.5",
64
+ "@types/node": "^20.11.27",
65
65
  "docdash": "^2.0.2",
66
66
  "ilib-lint-plugin-test": "file:test/ilib-lint-plugin-test",
67
67
  "ilib-lint-plugin-obsolete": "file:test/ilib-lint-plugin-obsolete",
68
68
  "i18nlint-plugin-test-old": "file:test/i18nlint-plugin-test-old",
69
69
  "jest": "^29.7.0",
70
70
  "jsdoc": "^4.0.2",
71
- "jsdoc-to-markdown": "^8.0.0",
71
+ "jsdoc-to-markdown": "^8.0.1",
72
72
  "npm-run-all": "^4.1.5",
73
- "typescript": "^5.2.2"
73
+ "typescript": "^5.4.2"
74
74
  },
75
75
  "dependencies": {
76
- "@formatjs/intl": "^2.9.3",
76
+ "@formatjs/intl": "^2.10.0",
77
77
  "ilib-common": "^1.1.3",
78
78
  "ilib-lint-common": "^3.0.0",
79
79
  "ilib-locale": "^1.2.2",
80
- "ilib-localeinfo": "^1.0.5",
81
- "ilib-tools-common": "^1.8.1",
80
+ "ilib-localeinfo": "^1.1.0",
81
+ "ilib-tools-common": "^1.9.1",
82
82
  "intl-messageformat": "^10.5",
83
83
  "json5": "^2.2.3",
84
84
  "log4js": "^6.9.1",
@@ -40,44 +40,6 @@ function checkVersion(json, name) {
40
40
  }
41
41
  }
42
42
 
43
- /**
44
- * @private
45
- */
46
- function attemptLoad(name) {
47
- logger.trace(`Trying module ${name}`);
48
- return import(name);
49
- };
50
-
51
- /**
52
- * Needed because node does not know how to load ES modules
53
- * from a path. (Even though that is what it does when you
54
- * just name the module without a path. Sigh.)
55
- *
56
- * @private
57
- */
58
- function attemptLoadPath(name) {
59
- logger.trace(`Trying directory module ${name}`);
60
- let packagePath = name;
61
- const packageName = path.join(name, "package.json");
62
- if (fs.existsSync(name) && fs.existsSync(packageName)) {
63
- const data = fs.readFileSync(packageName, "utf-8");
64
- const json = JSON.parse(data);
65
- checkVersion(json, name);
66
- if (json.type === "module") {
67
- let relativePath = json.module;
68
- if (!relativePath && json.exports) {
69
- const keys = Object.keys(json.exports);
70
- relativePath = keys.length && json.exports[keys[0]].import;
71
- }
72
- if (relativePath) {
73
- packagePath = path.join(name, relativePath);
74
- }
75
- }
76
- }
77
- logger.trace(`Path to this module is ${packagePath}`);
78
- return import(packagePath);
79
- }
80
-
81
43
  /**
82
44
  * @class Represent a plugin manager, which loads a list of plugins
83
45
  * and then maintains references to them
@@ -110,69 +72,112 @@ class PluginManager {
110
72
  this.resolve = createRequire(import.meta.url).resolve;
111
73
  }
112
74
 
75
+ /**
76
+ * Needed because node does not know how to load ES modules
77
+ * from a path. (Even though that is what it does when you
78
+ * just name the module without a path. Sigh.)
79
+ *
80
+ * @private
81
+ */
82
+ async attemptLoad(name) {
83
+ logger.trace(`Trying module ${name}`);
84
+ let packagePath = name;
85
+ const packageName = this.resolve(path.join(name, "package.json"));
86
+ if (fs.existsSync(packageName)) {
87
+ const data = fs.readFileSync(packageName, "utf-8");
88
+ const json = JSON.parse(data);
89
+ checkVersion(json, name);
90
+ if (json.type === "module") {
91
+ let relativePath = json.module;
92
+ if (!relativePath && json.exports) {
93
+ const keys = Object.keys(json.exports);
94
+ relativePath = keys.length && json.exports[keys[0]].import;
95
+ }
96
+ if (relativePath) {
97
+ packagePath = path.join(name, relativePath);
98
+ }
99
+ }
100
+ }
101
+ logger.trace(`Path to this module is ${packagePath}`);
102
+ return import(packagePath);
103
+ }
104
+
113
105
  /*
114
- * Attempt to load the plugin in various places:
106
+ * Attempt to load the plugin.
107
+ *
108
+ * If the name is given with an absolute or relative path,
109
+ * then it will only try to load from that path, as the caller
110
+ * meant to load a very specific plugin. If the name is given as
111
+ * just a package name, it will attemp to load from various places:
115
112
  *
116
- * - from the node_modules where ilib-lint was loaded
117
113
  * - from the current directory's node_modules
114
+ * - from the node_modules where ilib-lint was loaded
118
115
  * - from the plugins directory one directory up
116
+ * - from the global node_modules
119
117
  *
120
118
  * Each time it attempts to load it, it will try two ways:
121
119
  *
122
- * - As-is. Maybe it is a fully specified package name?
123
- * - With the "ilib-lint-" prefix. Try again except with
124
- * the prefix. This allows the users to configure plugins
125
- * in the config file more tersely, similar to the way
126
- * babel plugins can be named with only the unique part.
127
- * The old "i18nlint-" prefix is no longer accepted in
128
- * either the name of the directory or the name of the
129
- * package.
120
+ * - With the "ilib-lint-" prefix. Try with the prefix added to the
121
+ * name if it was not there already. This allows the users to configure
122
+ * plugins in the config file more tersely, similar to the way babel
123
+ * plugins can be named with only the unique part. The old "i18nlint-"
124
+ * prefix is no longer accepted in either the name of the directory
125
+ * or the name of the package.
126
+ * - As-is. Maybe it is a fully specified package name and doesn't have
127
+ * the prefix?
130
128
  *
131
129
  * @private
132
130
  */
133
- loadPlugin(name) {
134
- let pkgName = name;
135
- return attemptLoad(pkgName).catch(e1 => {
136
- logger.trace(e1);
137
- pkgName = `ilib-lint-${name}`;
138
- return attemptLoad(pkgName).catch(e2 => {
139
- logger.trace(e2);
140
- pkgName = path.join(process.cwd(), "node_modules", name);
141
- return attemptLoadPath(pkgName).catch(e3 => {
142
- logger.trace(e3);
143
- pkgName = path.join(process.cwd(), "node_modules", `ilib-lint-${name}`);
144
- return attemptLoadPath(pkgName).catch(e4 => {
145
- logger.trace(e4);
146
- pkgName = path.join(process.cwd(), "..", "plugins", name + ".js")
147
- return attemptLoad(pkgName).catch(e5 => {
148
- logger.trace(e5);
149
- // on the last attempt, don't catch the exception. Just let it
150
- // go to the overall `catch` clause below.
151
- pkgName = path.join(process.cwd(), "..", "plugins", `ilib-lint-${name}` + ".js")
152
- return attemptLoad(pkgName);
153
- });
154
- });
155
- });
156
- });
157
- }).then((module) => {
158
- logger.trace(`Module ${name} loaded with package name ${pkgName}.`);
159
- const modulePath = this.resolve(path.join(pkgName, "package.json"));
160
- const packageJsonContent = fs.readFileSync(modulePath, 'utf-8');
161
- const json = JSON.parse(packageJsonContent);
162
- checkVersion(json, name);
131
+ async loadPlugin(name) {
132
+ const nameparts = path.parse(name);
163
133
 
164
- logger.trace(`Module ${name} successfully loaded.`);
165
- const Main = module.default;
166
- const plugin = new Main({
167
- getLogger: log4js.getLogger.bind(log4js)
168
- });
169
- plugin.init();
170
- return plugin;
171
- }).catch(e2 => {
172
- logger.error(`Could not load plugin ${name}. If you have a plugin, make sure it is upgraded and depends on ilib-lint-common v3.0.0 or greater.`);
173
- logger.trace(e2);
134
+ let pathsToTry;
135
+ if (nameparts.dir && nameparts.dir !== ".") {
136
+ // If it's a relative or absolute path, then only try this path. Do not add
137
+ // any prefixes or try any other directory or anything.
138
+ pathsToTry = [name];
139
+ } else if (nameparts.base.startsWith("ilib-lint-")) {
140
+ pathsToTry = [
141
+ path.join(process.cwd(), "node_modules", nameparts.base),
142
+ name,
143
+ path.join(process.cwd(), "..", "plugins", nameparts.name + ".js")
144
+ ];
145
+ } else {
146
+ const base = `ilib-lint-${nameparts.base}`;
147
+ // try the paths with the ilib-lint prefix first, and then try the ones
148
+ // without afterwards
149
+ pathsToTry = [
150
+ path.join(process.cwd(), "node_modules", base),
151
+ base,
152
+ path.join(process.cwd(), "..", "plugins", `ilib-lint-${nameparts.name}` + ".js"),
153
+ path.join(process.cwd(), "node_modules", nameparts.base),
154
+ name,
155
+ path.join(process.cwd(), "..", "plugins", nameparts.name + ".js"),
156
+ ];
157
+ }
158
+
159
+ let pkgName, module;
160
+ while ((pkgName = pathsToTry.shift())) {
161
+ try {
162
+ module = await this.attemptLoad(pkgName);
163
+ break;
164
+ } catch (e) {
165
+ logger.trace(e);
166
+ }
167
+ }
168
+
169
+ if (!module) {
170
+ logger.error(`Could not load plugin ${name}. If you know that you have a plugin, make sure it is upgraded and depends on ilib-lint-common v3.0.0 or greater.`);
174
171
  return undefined;
172
+ }
173
+
174
+ logger.trace(`Module ${name} successfully loaded.`);
175
+ const Main = module.default;
176
+ const plugin = new Main({
177
+ getLogger: log4js.getLogger.bind(log4js)
175
178
  });
179
+ plugin.init();
180
+ return plugin;
176
181
  };
177
182
 
178
183
  /**
package/src/Project.js CHANGED
@@ -317,7 +317,7 @@ class Project extends DirItem {
317
317
  }
318
318
  }
319
319
  }
320
- this.formatter = fmtMgr.get(this.options.formatter || "ansi-console-formatter");
320
+ this.formatter = fmtMgr.get(this.options?.opt?.formatter || this.options.formatter || "ansi-console-formatter");
321
321
  if (!this.formatter) {
322
322
  logger.error(`Could not find formatter ${options.formatter}. Aborting...`);
323
323
  process.exit(3);