@backstage/eslint-plugin 0.1.3 → 0.1.4

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @backstage/eslint-plugin
2
2
 
3
+ ## 0.1.4
4
+
5
+ ### Patch Changes
6
+
7
+ - 107dc46: The `no-undeclared-imports` rule will now prefer using version queries that already exist en the repo for the same dependency type when installing new packages.
8
+
9
+ ## 0.1.4-next.0
10
+
11
+ ### Patch Changes
12
+
13
+ - 107dc46ab1: The `no-undeclared-imports` rule will now prefer using version queries that already exist en the repo for the same dependency type when installing new packages.
14
+
3
15
  ## 0.1.3
4
16
 
5
17
  ### Patch Changes
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@backstage/eslint-plugin",
3
3
  "description": "Backstage ESLint plugin",
4
- "version": "0.1.3",
4
+ "version": "0.1.4",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -22,7 +22,7 @@
22
22
  "minimatch": "^5.1.2"
23
23
  },
24
24
  "devDependencies": {
25
- "@backstage/cli": "^0.22.6",
25
+ "@backstage/cli": "^0.25.0",
26
26
  "eslint": "^8.33.0"
27
27
  }
28
28
  }
@@ -121,6 +121,39 @@ function getAddFlagForDepsField(depsField) {
121
121
  }
122
122
  }
123
123
 
124
+ /**
125
+ * Looks up the most common version range for a dependency if it already exists in the repo.
126
+ *
127
+ * @param {string} name
128
+ * @param {string} flag
129
+ * @param {getPackageMap.PackageMap} packages
130
+ * @returns {string}
131
+ */
132
+ function addVersionQuery(name, flag, packages) {
133
+ const rangeCounts = new Map();
134
+
135
+ for (const pkg of packages.list) {
136
+ const deps =
137
+ flag === '--dev'
138
+ ? pkg.packageJson.devDependencies
139
+ : flag === '--peer'
140
+ ? pkg.packageJson.peerDependencies
141
+ : pkg.packageJson.dependencies;
142
+ const range = deps?.[name];
143
+ if (range) {
144
+ rangeCounts.set(range, (rangeCounts.get(range) ?? 0) + 1);
145
+ }
146
+ }
147
+
148
+ const mostCommonRange = [...rangeCounts.entries()].sort(
149
+ (a, b) => b[1] - a[1],
150
+ )[0]?.[0];
151
+ if (!mostCommonRange) {
152
+ return name;
153
+ }
154
+ return `${name}@${mostCommonRange}`;
155
+ }
156
+
124
157
  /** @type {import('eslint').Rule.RuleModule} */
125
158
  module.exports = {
126
159
  meta: {
@@ -177,13 +210,22 @@ module.exports = {
177
210
  }
178
211
 
179
212
  for (const [flag, names] of Object.entries(byFlag)) {
213
+ // Look up existing version queries in the repo for the same dependency
214
+ const namesWithQuery = [...names].map(name =>
215
+ addVersionQuery(name, flag, packages),
216
+ );
217
+
180
218
  // The security implication of this is a bit interesting, as crafted add-import
181
219
  // directives could be used to install malicious packages. However, the same is true
182
- // for adding malicious packages to package.json, so there's significant difference.
183
- execFileSync('yarn', ['add', ...(flag ? [flag] : []), ...names], {
184
- cwd: localPkg.dir,
185
- stdio: 'inherit',
186
- });
220
+ // for adding malicious packages to package.json, so there's no significant difference.
221
+ execFileSync(
222
+ 'yarn',
223
+ ['add', ...(flag ? [flag] : []), ...namesWithQuery],
224
+ {
225
+ cwd: localPkg.dir,
226
+ stdio: 'inherit',
227
+ },
228
+ );
187
229
  }
188
230
 
189
231
  // This switches all import directives back to the original import.