Skip to content

Commit

Permalink
allow platform to be set with an option
Browse files Browse the repository at this point in the history
  • Loading branch information
isaacs committed Feb 24, 2023
1 parent 5f3438d commit 58917fe
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 12 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,14 @@ is equivalent in all cases).
string is first processed with
`minimatch.levelTwoFileOptimize()` or similar.

### platform

When set to `win32`, this will trigger all windows-specific
behaviors (special handling for UNC paths, and treating `\` as
separators in file paths for comparison.)

Defaults to the value of `process.platform`.

## Comparisons to other fnmatch/glob implementations

While strict compliance with the existing standards is a
Expand Down
26 changes: 17 additions & 9 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export interface MinimatchOptions {
flipNegate?: boolean
preserveMultipleSlashes?: boolean
optimizationLevel?: number
platform?: typeof process.platform
}

export const minimatch = (
Expand Down Expand Up @@ -87,19 +88,21 @@ const qmarksTestNoExtDot = ([$0]: RegExpMatchArray) => {
return (f: string) => f.length === len && f !== '.' && f !== '..'
}

type Platform = typeof process.platform
/* c8 ignore start */
const platform =
const defaultPlatform: Platform = (
typeof process === 'object' && process
? (typeof process.env === 'object' &&
process.env &&
process.env.__MINIMATCH_TESTING_PLATFORM__) ||
process.platform
: 'posix'
const isWindows = platform === 'win32'
const path = isWindows ? { sep: '\\' } : { sep: '/' }
) as Platform
type Sep = '\\' | '/'
const path:{[k:string]:{sep:Sep}} = { win32: { sep: '\\' }, posix: { sep: '/' } }
/* c8 ignore stop */

export const sep = path.sep
export const sep = defaultPlatform === 'win32' ? path.win32.sep : path.posix.sep
minimatch.sep = sep

export const GLOBSTAR = Symbol('globstar **')
Expand Down Expand Up @@ -306,13 +309,18 @@ export class Minimatch {
globSet: string[]
globParts: string[][]

isWindows: boolean
platform: typeof process.platform

regexp: false | null | MMRegExp
constructor(pattern: string, options: MinimatchOptions = {}) {
assertValidPattern(pattern)

options = options || {}
this.options = options
this.pattern = pattern
this.platform = options.platform || defaultPlatform
this.isWindows = this.platform === 'win32'
this.windowsPathsNoEscape =
!!options.windowsPathsNoEscape || options.allowWindowsEscape === false
if (this.windowsPathsNoEscape) {
Expand Down Expand Up @@ -387,7 +395,7 @@ export class Minimatch {
) as ParseReturnFiltered[][]

// do not treat the ? in UNC paths as magic
if (isWindows) {
if (this.isWindows) {
for (let i = 0; i < this.set.length; i++) {
const p = this.set[i]
if (
Expand Down Expand Up @@ -710,7 +718,7 @@ export class Minimatch {

// a UNC pattern like //?/c:/* can match a path like c:/x
// and vice versa
if (isWindows) {
if (this.isWindows) {
const fileUNC =
file[0] === '' &&
file[1] === '' &&
Expand Down Expand Up @@ -1452,7 +1460,7 @@ export class Minimatch {
// preserveMultipleSlashes is set to true.
if (this.preserveMultipleSlashes) {
return p.split('/')
} else if (isWindows && /^\/\/[^\/]+/.test(p)) {
} else if (this.isWindows && /^\/\/[^\/]+/.test(p)) {
// add an extra '' for the one we lose
return ['', ...p.split(/\/+/)]
} else {
Expand All @@ -1478,8 +1486,8 @@ export class Minimatch {
const options = this.options

// windows: need to use /, not \
if (path.sep !== '/') {
f = f.split(path.sep).join('/')
if (this.isWindows) {
f = f.split('\\').join('/')
}

// treat the test path as a set of pathparts.
Expand Down
6 changes: 3 additions & 3 deletions test/unc.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
process.env.__MINIMATCH_TESTING_PLATFORM__ = 'win32'
import t from 'tap'
import { minimatch, Minimatch, MinimatchOptions } from '../'

t.test('UNC patterns do not lose their //', async t => {
const share = new Minimatch('//host/share/*')
const share = new Minimatch('//host/share/*', { platform: 'win32' })
t.match(share.set, [['', '', 'host', 'share', RegExp]])
const uncPath = new Minimatch('//?/d:/*')
const uncPath = new Minimatch('//?/d:/*', { platform: 'win32' })
t.match(uncPath.set, [['', '', '?', 'd:', RegExp]])
})

Expand Down Expand Up @@ -34,6 +33,7 @@ const cases: Case[] = [

t.test('UNC drive letter paths match normal paths', async t => {
for (const [file, pattern, expect, opt = {}] of cases) {
opt.platform = 'win32'
t.test(`f=${file} p=${pattern}`, t => {
t.test('/ only', t => {
t.equal(minimatch(file, pattern, opt), expect)
Expand Down

0 comments on commit 58917fe

Please sign in to comment.