Skip to content

Commit

Permalink
add windowsNoMagicRoot
Browse files Browse the repository at this point in the history
  • Loading branch information
isaacs committed Feb 26, 2023
1 parent f050a22 commit 559b9ad
Show file tree
Hide file tree
Showing 5 changed files with 281 additions and 1 deletion.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,16 @@ paths](#windows).
For legacy reasons, this is also set if
`options.allowWindowsEscape` is set to the exact value `false`.

### windowsNoMagicRoot

When a pattern starts with a UNC path or drive letter, and in
`nocase:true` mode, do not convert the root portions of the
pattern into a case-insensitive regular expression, and instead
leave them as strings.

This is the default when the platform is `win32` and
`nocase:true` is set.

### preserveMultipleSlashes

By default, multiple `/` characters (other than the leading `//`
Expand Down
4 changes: 4 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# change log

## 7.2

- Add `windowsNoMagicRoot` option

## 7.1

- Add `optimizationLevel` configuration option, and revert the
Expand Down
27 changes: 26 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export interface MinimatchOptions {
preserveMultipleSlashes?: boolean
optimizationLevel?: number
platform?: typeof process.platform
windowsNoMagicRoot?: boolean
}

export const minimatch = (
Expand Down Expand Up @@ -272,6 +273,7 @@ minimatch.match = match

// replace stuff like \* with *
const globUnescape = (s: string) => s.replace(/\\(.)/g, '$1')
const globMagic = /[?*]|[+@!]\(.*?\)|\[|\]/
const charUnescape = (s: string) => s.replace(/\\([^-\]])/g, '$1')
const regExpEscape = (s: string) =>
s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')
Expand Down Expand Up @@ -311,9 +313,11 @@ export class Minimatch {
partial: boolean
globSet: string[]
globParts: string[][]
nocase: boolean

isWindows: boolean
platform: typeof process.platform
windowsNoMagicRoot: boolean

regexp: false | null | MMRegExp
constructor(pattern: string, options: MinimatchOptions = {}) {
Expand All @@ -336,6 +340,11 @@ export class Minimatch {
this.comment = false
this.empty = false
this.partial = !!options.partial
this.nocase = !!this.options.nocase
this.windowsNoMagicRoot =
options.windowsNoMagicRoot !== undefined
? options.windowsNoMagicRoot
: !!(this.isWindows && this.nocase)

this.globSet = []
this.globParts = []
Expand Down Expand Up @@ -388,7 +397,23 @@ export class Minimatch {
this.debug(this.pattern, this.globParts)

// glob --> regexps
let set = this.globParts.map((s, _, __) => s.map(ss => this.parse(ss)))
let set = this.globParts.map((s, _, __) => {
if (this.isWindows && this.windowsNoMagicRoot) {
// check if it's a drive or unc path.
const isUNC =
s[0] === '' &&
s[1] === '' &&
(s[2] === '?' || !globMagic.test(s[2])) &&
!globMagic.test(s[3])
const isDrive = /^[a-z]:/i.test(s[0])
if (isUNC) {
return [...s.slice(0, 4), ...s.slice(4).map(ss => this.parse(ss))]
} else if (isDrive) {
return [s[0], ...s.slice(1).map(ss => this.parse(ss))]
}
}
return s.map(ss => this.parse(ss))
})

this.debug(this.pattern, set)

Expand Down
210 changes: 210 additions & 0 deletions tap-snapshots/test/windows-no-magic-root.ts.test.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
/* IMPORTANT
* This snapshot file is auto-generated, but designed for humans.
* It should be checked into source control and tracked carefully.
* Re-generate by setting TAP_SNAPSHOT=1 and running tests.
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/windows-no-magic-root.ts TAP no magic the root //?/d: > default to true 1`] = `
Array [
Array [
"",
"",
"?",
"d:",
],
]
`

exports[`test/windows-no-magic-root.ts TAP no magic the root //?/d: > set explicitly false 1`] = `
Array [
Array [
"",
"",
/^(?!\\.)(?=.)[^/]$/i,
/^d:$/i,
],
]
`

exports[`test/windows-no-magic-root.ts TAP no magic the root //?/d:/ > default to true 1`] = `
Array [
Array [
"",
"",
"?",
"d:",
"",
],
]
`

exports[`test/windows-no-magic-root.ts TAP no magic the root //?/d:/ > set explicitly false 1`] = `
Array [
Array [
"",
"",
/^(?!\\.)(?=.)[^/]$/i,
/^d:$/i,
"",
],
]
`

exports[`test/windows-no-magic-root.ts TAP no magic the root //?/d:/x/y/z > default to true 1`] = `
Array [
Array [
"",
"",
"?",
"d:",
/^x$/i,
/^y$/i,
/^z$/i,
],
]
`

exports[`test/windows-no-magic-root.ts TAP no magic the root //?/d:/x/y/z > set explicitly false 1`] = `
Array [
Array [
"",
"",
/^(?!\\.)(?=.)[^/]$/i,
/^d:$/i,
/^x$/i,
/^y$/i,
/^z$/i,
],
]
`

exports[`test/windows-no-magic-root.ts TAP no magic the root //host/share > default to true 1`] = `
Array [
Array [
"",
"",
"host",
"share",
],
]
`

exports[`test/windows-no-magic-root.ts TAP no magic the root //host/share > set explicitly false 1`] = `
Array [
Array [
"",
"",
/^host$/i,
/^share$/i,
],
]
`

exports[`test/windows-no-magic-root.ts TAP no magic the root //host/share/ > default to true 1`] = `
Array [
Array [
"",
"",
"host",
"share",
"",
],
]
`

exports[`test/windows-no-magic-root.ts TAP no magic the root //host/share/ > set explicitly false 1`] = `
Array [
Array [
"",
"",
/^host$/i,
/^share$/i,
"",
],
]
`

exports[`test/windows-no-magic-root.ts TAP no magic the root //host/share/x/y/z > default to true 1`] = `
Array [
Array [
"",
"",
"host",
"share",
/^x$/i,
/^y$/i,
/^z$/i,
],
]
`

exports[`test/windows-no-magic-root.ts TAP no magic the root //host/share/x/y/z > set explicitly false 1`] = `
Array [
Array [
"",
"",
/^host$/i,
/^share$/i,
/^x$/i,
/^y$/i,
/^z$/i,
],
]
`

exports[`test/windows-no-magic-root.ts TAP no magic the root d: > default to true 1`] = `
Array [
Array [
"d:",
],
]
`

exports[`test/windows-no-magic-root.ts TAP no magic the root d: > set explicitly false 1`] = `
Array [
Array [
/^d:$/i,
],
]
`

exports[`test/windows-no-magic-root.ts TAP no magic the root d:/ > default to true 1`] = `
Array [
Array [
"d:",
"",
],
]
`

exports[`test/windows-no-magic-root.ts TAP no magic the root d:/ > set explicitly false 1`] = `
Array [
Array [
/^d:$/i,
"",
],
]
`

exports[`test/windows-no-magic-root.ts TAP no magic the root d:/x/y/z > default to true 1`] = `
Array [
Array [
"d:",
/^x$/i,
/^y$/i,
/^z$/i,
],
]
`

exports[`test/windows-no-magic-root.ts TAP no magic the root d:/x/y/z > set explicitly false 1`] = `
Array [
Array [
/^d:$/i,
/^x$/i,
/^y$/i,
/^z$/i,
],
]
`
31 changes: 31 additions & 0 deletions test/windows-no-magic-root.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import {Minimatch} from '../'
import t from 'tap'

t.test('no magic the root', t => {
const patterns = [
'//host/share/x/y/z',
'//host/share/',
'//host/share',
'//?/d:/x/y/z',
'//?/d:/',
'//?/d:',
'd:/x/y/z',
'd:/',
'd:',
]
t.plan(patterns.length)
for (const p of patterns) {
t.test(p, t => {
t.matchSnapshot(new Minimatch(p, {
platform: 'win32',
nocase: true,
}).set, 'default to true')
t.matchSnapshot(new Minimatch(p, {
windowsNoMagicRoot: false,
platform: 'win32',
nocase: true,
}).set, 'set explicitly false')
t.end()
})
}
})

0 comments on commit 559b9ad

Please sign in to comment.