From dcae53b754376c8501b3f1777c755b238e34af91 Mon Sep 17 00:00:00 2001 From: neverland Date: Tue, 4 Aug 2026 22:45:59 +0800 Subject: [PATCH] fix(fmt): use ignore for pattern matching --- packages/rstack/THIRD_PARTY_NOTICES.md | 28 ------------------------ packages/rstack/package.json | 1 - packages/rstack/src/fmt/ignore.ts | 15 +++++++++---- packages/rstack/tests/fmt/ignore.test.ts | 8 +++++++ pnpm-lock.yaml | 24 -------------------- pnpm-workspace.yaml | 1 - 6 files changed, 19 insertions(+), 58 deletions(-) diff --git a/packages/rstack/THIRD_PARTY_NOTICES.md b/packages/rstack/THIRD_PARTY_NOTICES.md index 048171d..7348005 100644 --- a/packages/rstack/THIRD_PARTY_NOTICES.md +++ b/packages/rstack/THIRD_PARTY_NOTICES.md @@ -59,34 +59,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -## fast-ignore - -This package includes bundled code from [fast-ignore](https://github.com/fabiospampinato/fast-ignore). - -License: MIT - -The MIT License (MIT) - -Copyright (c) 2023-present Fabio Spampinato - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - ## fresh-import This package includes bundled code from [fresh-import](https://github.com/sapphi-red/fresh-import). diff --git a/packages/rstack/package.json b/packages/rstack/package.json index 6bd9e14..1c542aa 100644 --- a/packages/rstack/package.json +++ b/packages/rstack/package.json @@ -69,7 +69,6 @@ "@rstest/adapter-rslib": "catalog:", "@types/micromatch": "catalog:", "@types/node": "catalog:", - "fast-ignore": "catalog:", "ignore": "catalog:", "import-meta-resolve": "catalog:", "is-binary-path": "catalog:", diff --git a/packages/rstack/src/fmt/ignore.ts b/packages/rstack/src/fmt/ignore.ts index 0813098..b27ce88 100644 --- a/packages/rstack/src/fmt/ignore.ts +++ b/packages/rstack/src/fmt/ignore.ts @@ -1,6 +1,6 @@ import { readFile } from 'node:fs/promises'; import path from 'node:path'; -import fastIgnore from 'fast-ignore'; +import createIgnore from 'ignore'; import type { ResolvedFmtConfig } from './types.ts'; /** @@ -21,10 +21,17 @@ interface CreateIgnoreMatcherOptions { } const createPatternMatcher = (rootPath: string, patterns: string): IgnoreMatcher => { - const matches = fastIgnore(patterns); + const matcher = createIgnore({ allowRelativePaths: true }).add(patterns); - return (filePath, isDirectory = false) => - matches(path.relative(rootPath, filePath), { isDirectory }); + return (filePath, isDirectory = false) => { + const relativePath = path.relative(rootPath, filePath); + if (relativePath === '') { + return false; + } + + const posixPath = path.sep === '\\' ? relativePath.replaceAll('\\', '/') : relativePath; + return matcher.ignores(isDirectory ? `${posixPath}/` : posixPath); + }; }; const loadIgnoreMatcher = async (cwd: string, ignorePath: string): Promise => { diff --git a/packages/rstack/tests/fmt/ignore.test.ts b/packages/rstack/tests/fmt/ignore.test.ts index 192ff6a..5826767 100644 --- a/packages/rstack/tests/fmt/ignore.test.ts +++ b/packages/rstack/tests/fmt/ignore.test.ts @@ -38,6 +38,14 @@ test('distinguishes directory-only patterns from files', async () => { expect(isIgnored(path.join(directoryPath, 'index.js'))).toBe(true); }); +test('does not apply negated directory patterns to files', async () => { + const isIgnored = await createMatcher(['fixtures/**/*', '!fixtures/**/']); + const directoryPath = path.join(rootPath, 'fixtures/case'); + + expect(isIgnored(directoryPath, true)).toBe(false); + expect(isIgnored(path.join(directoryPath, 'index.js'))).toBe(true); +}); + test('applies negated patterns in declaration order', async () => { const isIgnored = await createMatcher(['*.js', '!src/keep.js']); const isIgnoredAgain = await createMatcher(['*.js', '!src/keep.js', 'src/keep.js']); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8c3c623..b461347 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -76,9 +76,6 @@ catalogs: cspell-ban-words: specifier: ^0.0.4 version: 0.0.4 - fast-ignore: - specifier: 2.0.0 - version: 2.0.0 happy-dom: specifier: ^20.11.1 version: 20.11.1 @@ -370,9 +367,6 @@ importers: '@types/node': specifier: 'catalog:' version: 24.13.3 - fast-ignore: - specifier: 'catalog:' - version: 2.0.0 ignore: specifier: 'catalog:' version: 7.0.6 @@ -1503,9 +1497,6 @@ packages: extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - fast-ignore@2.0.0: - resolution: {integrity: sha512-41OOPBgTDyVjF2oytGXvmqm56a38znzWLTQhvD3gp3FPCs37+j7qYjWDnL2WEA0P/Z80W53MKAXNJxc0JT8Tpw==} - fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} engines: {node: '>=12.0.0'} @@ -1529,9 +1520,6 @@ packages: git-hooks-list@4.2.1: resolution: {integrity: sha512-WNvqJjOxxs/8ZP9+DWdwWJ7cDsd60NHf39XnD82pDVrKO5q7xfPqpkK6hwEAmBa/ZSEE4IOoR75EzbbIuwGlMw==} - grammex@3.1.13: - resolution: {integrity: sha512-LnPnhOBLEJEVKS8WFDVaA397L9Kq55Q9oSITJiVLHVdhAclfUkWzQv74KhvZHKL2Q09Pb1XdsrOsZ4LfTFFTEg==} - happy-dom@20.11.1: resolution: {integrity: sha512-XSt8tMzbW9ymE7687xztkO1ckR7qJNQ3LywY9vlYGhGi3zXrGBHuUo2Cl1ztZaICW+1eAGdkLbj6iwVqDT33kg==} engines: {node: '>=20.0.0'} @@ -2265,9 +2253,6 @@ packages: resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} engines: {node: '>=0.6.19'} - string-escape-regex@1.0.1: - resolution: {integrity: sha512-cdSXOHSJ32K/T2dbj9t7rJwonujaOkaINpa1zsXT+PNFIv1zuPjtr0tXanCvUhN2bIu2IB0z/C7ksl+Qsy44nA==} - stringify-entities@4.0.4: resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} @@ -3315,11 +3300,6 @@ snapshots: extend@3.0.2: {} - fast-ignore@2.0.0: - dependencies: - grammex: 3.1.13 - string-escape-regex: 1.0.1 - fdir@6.5.0(picomatch@4.0.5): optionalDependencies: picomatch: 4.0.5 @@ -3334,8 +3314,6 @@ snapshots: git-hooks-list@4.2.1: {} - grammex@3.1.13: {} - happy-dom@20.11.1: dependencies: '@types/node': 24.13.3 @@ -4424,8 +4402,6 @@ snapshots: string-argv@0.3.2: {} - string-escape-regex@1.0.1: {} - stringify-entities@4.0.4: dependencies: character-entities-html4: 2.1.0 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index b19b744..2d5bb31 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -35,7 +35,6 @@ catalog: '@types/react-dom': '^19.2.4' '@shikijs/transformers': '^4.3.1' 'cspell-ban-words': '^0.0.4' - 'fast-ignore': '2.0.0' 'happy-dom': '^20.11.1' 'heading-case': '^1.1.4' ignore: 7.0.6