Skip to content

Commit e66575f

Browse files
authored
refactor: revert picomatch back to minimatch (#256)
1 parent 7a9c412 commit e66575f

14 files changed

+287
-274
lines changed

.changeset/red-pumpkins-tease.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"eslint-plugin-import-x": patch
3+
---
4+
5+
refactor: revert `picomatch` back to `minimatch`

.github/workflows/pkg-pr-new.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,4 @@ jobs:
2727
- name: Build
2828
run: yarn build
2929

30-
- run: yarn dlx pkg-pr-new publish
30+
- run: yarn dlx pkg-pr-new publish --compact

package.json

+11-10
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"version": "4.9.0",
44
"type": "commonjs",
55
"description": "Import with sanity.",
6-
"repository": "git+https://github.com/un-ts/eslint-plugin-import-x",
6+
"repository": "https://github.com/un-ts/eslint-plugin-import-x",
77
"author": "JounQin <[email protected]> (https://www.1stG.me)",
88
"license": "MIT",
99
"packageManager": "[email protected]",
@@ -49,13 +49,14 @@
4949
},
5050
"dependencies": {
5151
"@types/doctrine": "^0.0.9",
52-
"@typescript-eslint/utils": "^8.26.1",
52+
"@typescript-eslint/utils": "^8.27.0",
5353
"debug": "^4.4.0",
5454
"doctrine": "^3.0.0",
5555
"eslint-import-resolver-node": "^0.3.9",
5656
"get-tsconfig": "^4.10.0",
57-
"picomatch": "^4.0.2",
58-
"rspack-resolver": "^1.2.1",
57+
"is-glob": "^4.0.3",
58+
"minimatch": "^10.0.1",
59+
"rspack-resolver": "^1.2.2",
5960
"semver": "^7.7.1",
6061
"stable-hash": "^0.0.5",
6162
"tslib": "^2.8.1"
@@ -89,22 +90,22 @@
8990
"@types/debug": "^4.1.12",
9091
"@types/eslint": "^9.6.1",
9192
"@types/eslint8.56": "npm:@types/eslint@~8.56.0",
93+
"@types/is-glob": "^4.0.4",
9294
"@types/jest": "^29.5.14",
9395
"@types/json-schema": "^7.0.15",
9496
"@types/klaw-sync": "^6.0.5",
9597
"@types/node": "^20.17.24",
96-
"@types/picomatch": "^3.0.2",
9798
"@types/pnpapi": "^0.0.5",
98-
"@typescript-eslint/eslint-plugin": "^8.26.1",
99-
"@typescript-eslint/parser": "^8.26.1",
100-
"@typescript-eslint/rule-tester": "^8.26.1",
99+
"@typescript-eslint/eslint-plugin": "^8.27.0",
100+
"@typescript-eslint/parser": "^8.27.0",
101+
"@typescript-eslint/rule-tester": "^8.27.0",
101102
"@unts/patch-package": "^8.1.1",
102103
"clean-pkg-json": "^1.2.1",
103104
"cross-env": "^7.0.3",
104105
"eslint": "^9.22.0",
105106
"eslint-config-prettier": "^10.1.1",
106107
"eslint-doc-generator": "^2.1.2",
107-
"eslint-import-resolver-typescript": "^4.2.1",
108+
"eslint-import-resolver-typescript": "^4.2.2",
108109
"eslint-import-resolver-webpack": "^0.13.10",
109110
"eslint-import-test-order-redirect": "link:./test/fixtures/order-redirect",
110111
"eslint-plugin-eslint-plugin": "^6.4.0",
@@ -120,7 +121,7 @@
120121
"eslint9": "npm:eslint@^9.22.0",
121122
"hermes-eslint": "^0.26.0",
122123
"jest": "^29.7.0",
123-
"klaw-sync": "^6.0.0",
124+
"klaw-sync": "^7.0.0",
124125
"lint-staged": "^15.5.0",
125126
"npm-run-all2": "^7.0.2",
126127
"path-serializer": "^0.3.4",

src/rules/no-extraneous-dependencies.ts

+11-6
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import fs from 'node:fs'
22
import path from 'node:path'
33

44
import type { TSESTree } from '@typescript-eslint/utils'
5+
import { minimatch } from 'minimatch'
56
import type { PackageJson } from 'type-fest'
67

78
import type { RuleContext } from '../types'
@@ -12,7 +13,6 @@ import {
1213
pkgUp,
1314
importType,
1415
getFilePackageName,
15-
isFileMatch,
1616
} from '../utils'
1717

1818
type PackageDeps = ReturnType<typeof extractDepFields>
@@ -329,11 +329,16 @@ function reportIfMissing(
329329
}
330330

331331
function testConfig(config: string[] | boolean | undefined, filename: string) {
332-
return Array.isArray(config)
333-
? // Array of globs.
334-
isFileMatch(filename, config)
335-
: // Simplest configuration first, either a boolean or nothing.
336-
config
332+
// Simplest configuration first, either a boolean or nothing.
333+
if (typeof config === 'boolean' || config === undefined) {
334+
return config
335+
}
336+
// Array of globs.
337+
return config.some(
338+
c =>
339+
minimatch(filename, c) ||
340+
minimatch(filename, path.resolve(c), { windowsPathsNoEscape: true }),
341+
)
337342
}
338343

339344
type Options = {

src/rules/no-import-module-exports.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import path from 'node:path'
22

33
import type { TSESLint, TSESTree } from '@typescript-eslint/utils'
4+
import { minimatch } from 'minimatch'
45

56
import type { RuleContext } from '../types'
6-
import { createRule, matcher, pkgUp } from '../utils'
7+
import { createRule, pkgUp } from '../utils'
78

89
function getEntryPoint(context: RuleContext) {
910
const pkgPath = pkgUp({
@@ -78,8 +79,6 @@ export = createRule<[Options?], MessageId>({
7879

7980
let alreadyReported = false
8081

81-
const isMatch = matcher(options.exceptions)
82-
8382
return {
8483
ImportDeclaration(node) {
8584
importDeclarations.push(node)
@@ -112,7 +111,7 @@ export = createRule<[Options?], MessageId>({
112111
isIdentifier &&
113112
hasCJSExportReference &&
114113
!isEntryPoint &&
115-
!isMatch(filename) &&
114+
!options.exceptions?.some(glob => minimatch(filename, glob)) &&
116115
!isImportBinding
117116
) {
118117
for (const importDeclaration of importDeclarations) {

src/rules/no-internal-modules.ts

+11-15
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
1-
import {
2-
importType,
3-
createRule,
4-
moduleVisitor,
5-
resolve,
6-
matcher,
7-
} from '../utils'
8-
9-
// picomatch patterns are expected to use / path separators, like import
1+
import { makeRe } from 'minimatch'
2+
3+
import { importType, createRule, moduleVisitor, resolve } from '../utils'
4+
5+
// minimatch patterns are expected to use / path separators, like import
106
// statements, so normalize paths to use the same
117
function normalizeSep(somePath: string) {
128
return somePath.split('\\').join('/')
@@ -84,21 +80,21 @@ export = createRule<[Options?], MessageId>({
8480
defaultOptions: [],
8581
create(context) {
8682
const options = context.options[0] || {}
87-
const allowMatches = (options.allow || [])
88-
.map(p => matcher(p))
83+
const allowRegexps = (options.allow || [])
84+
.map(p => makeRe(p))
8985
.filter(Boolean)
90-
const forbidMatches = (options.forbid || [])
91-
.map(p => matcher(p))
86+
const forbidRegexps = (options.forbid || [])
87+
.map(p => makeRe(p))
9288
.filter(Boolean)
9389

9490
// test if reaching to this destination is allowed
9591
function reachingAllowed(importPath: string) {
96-
return allowMatches.some(m => m(importPath))
92+
return allowRegexps.some(re => re.test(importPath))
9793
}
9894

9995
// test if reaching to this destination is forbidden
10096
function reachingForbidden(importPath: string) {
101-
return forbidMatches.some(m => m(importPath))
97+
return forbidRegexps.some(re => re.test(importPath))
10298
}
10399

104100
function isAllowViolation(importPath: string) {

src/rules/no-namespace.ts

+7-4
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
*/
44

55
import type { TSESLint, TSESTree } from '@typescript-eslint/utils'
6+
import { minimatch } from 'minimatch'
67

7-
import { createRule, matcher } from '../utils'
8+
import { createRule } from '../utils'
89

910
type MessageId = 'noNamespace'
1011

@@ -44,11 +45,13 @@ export = createRule<[Options?], MessageId>({
4445
const firstOption = context.options[0] || {}
4546
const ignoreGlobs = firstOption.ignore
4647

47-
const isMatch = matcher(ignoreGlobs, { matchBase: true })
48-
4948
return {
5049
ImportNamespaceSpecifier(node) {
51-
if (isMatch(node.parent.source.value)) {
50+
if (
51+
ignoreGlobs?.find(glob =>
52+
minimatch(node.parent.source.value, glob, { matchBase: true }),
53+
)
54+
) {
5255
return
5356
}
5457

src/rules/no-restricted-paths.ts

+15-16
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,21 @@
11
import path from 'node:path'
22

33
import type { TSESTree } from '@typescript-eslint/utils'
4+
import isGlob from 'is-glob'
5+
import { Minimatch } from 'minimatch'
46

57
import type { Arrayable } from '../types'
6-
import {
7-
importType,
8-
createRule,
9-
moduleVisitor,
10-
resolve,
11-
isDynamicPattern,
12-
fileMatcher,
13-
isMatch,
14-
} from '../utils'
8+
import { importType, createRule, moduleVisitor, resolve } from '../utils'
159

1610
const containsPath = (filepath: string, target: string) => {
1711
const relative = path.relative(target, filepath)
1812
return relative === '' || !relative.startsWith('..')
1913
}
2014

2115
function isMatchingTargetPath(filename: string, targetPath: string) {
22-
if (isDynamicPattern(targetPath)) {
23-
return isMatch(filename, targetPath)
16+
if (isGlob(targetPath)) {
17+
const mm = new Minimatch(targetPath, { windowsPathsNoEscape: true })
18+
return mm.match(filename)
2419
}
2520

2621
return containsPath(filename, targetPath)
@@ -176,13 +171,17 @@ export = createRule<[Options?], MessageId>({
176171
) {
177172
let isPathException: ((absoluteImportPath: string) => boolean) | undefined
178173

179-
const isPathRestricted = fileMatcher(absoluteFrom)
180-
const hasValidExceptions = zoneExcept.every(it => isDynamicPattern(it))
174+
const mm = new Minimatch(absoluteFrom, { windowsPathsNoEscape: true })
175+
const isPathRestricted = (absoluteImportPath: string) =>
176+
mm.match(absoluteImportPath)
177+
const hasValidExceptions = zoneExcept.every(it => isGlob(it))
181178

182179
if (hasValidExceptions) {
183-
const exceptionsMm = zoneExcept.map(except => fileMatcher(except))
180+
const exceptionsMm = zoneExcept.map(
181+
except => new Minimatch(except, { windowsPathsNoEscape: true }),
182+
)
184183
isPathException = (absoluteImportPath: string) =>
185-
exceptionsMm.some(mm => mm(absoluteImportPath))
184+
exceptionsMm.some(mm => mm.match(absoluteImportPath))
186185
}
187186

188187
const reportInvalidException = reportInvalidExceptionGlob
@@ -259,7 +258,7 @@ export = createRule<[Options?], MessageId>({
259258
zoneExcept: string[] = [],
260259
) => {
261260
const allZoneFrom = [zoneFrom].flat()
262-
const areGlobPatterns = allZoneFrom.map(it => isDynamicPattern(it))
261+
const areGlobPatterns = allZoneFrom.map(it => isGlob(it))
263262

264263
if (areBothGlobPatternAndAbsolutePath(areGlobPatterns)) {
265264
return [computeMixedGlobAndAbsolutePathValidator()]

src/rules/no-unassigned-import.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import path from 'node:path'
22

3-
import { isStaticRequire, createRule, isFileMatch } from '../utils'
3+
import { minimatch } from 'minimatch'
4+
5+
import { isStaticRequire, createRule } from '../utils'
46

57
function testIsAllow(
68
globs: string[] | undefined,
@@ -17,7 +19,11 @@ function testIsAllow(
1719
? source
1820
: path.resolve(filename, '..', source) // get source absolute path
1921

20-
return isFileMatch(filePath, globs)
22+
return globs.some(
23+
glob =>
24+
minimatch(filePath, glob) ||
25+
minimatch(filePath, path.resolve(glob), { windowsPathsNoEscape: true }),
26+
)
2127
}
2228

2329
type Options = {

src/rules/order.ts

+3-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { TSESLint, TSESTree } from '@typescript-eslint/utils'
22
import debug from 'debug'
3+
import { minimatch } from 'minimatch'
34

45
import type {
56
AlphabetizeOptions,
@@ -16,13 +17,7 @@ import type {
1617
RanksPathGroup,
1718
RuleContext,
1819
} from '../types'
19-
import {
20-
createRule,
21-
getValue,
22-
importType,
23-
isMatch,
24-
isStaticRequire,
25-
} from '../utils'
20+
import { getValue, importType, isStaticRequire, createRule } from '../utils'
2621

2722
const log = debug('eslint-plugin-import-x:rules:order')
2823

@@ -706,7 +701,7 @@ function computePathRank(
706701
maxPosition: number,
707702
) {
708703
for (const { pattern, patternOptions, group, position = 1 } of pathGroups) {
709-
if (isMatch(path, pattern, patternOptions)) {
704+
if (minimatch(path, pattern, patternOptions || { nocomment: true })) {
710705
return ranks[group] + position / maxPosition
711706
}
712707
}

src/types.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { TSESLint, TSESTree } from '@typescript-eslint/utils'
2-
import type { PicomatchOptions } from 'picomatch'
2+
import type { MinimatchOptions } from 'minimatch'
33
import type { NapiResolveOptions as ResolveOptions } from 'rspack-resolver'
44
import type { KebabCase } from 'type-fest'
55

@@ -167,7 +167,7 @@ export type ExportNamespaceSpecifier = CustomESTreeNode<
167167
export type PathGroup = {
168168
pattern: string
169169
group: ImportType
170-
patternOptions?: PicomatchOptions
170+
patternOptions?: MinimatchOptions
171171
position?: 'before' | 'after'
172172
}
173173

@@ -225,7 +225,7 @@ export type ImportEntryWithRank = {
225225

226226
export type RanksPathGroup = {
227227
pattern: string
228-
patternOptions?: PicomatchOptions
228+
patternOptions?: MinimatchOptions
229229
group: string
230230
position?: number
231231
}

0 commit comments

Comments
 (0)