diff --git a/README.md b/README.md index 36a43021..a5bdefaa 100644 --- a/README.md +++ b/README.md @@ -201,6 +201,21 @@ minimatch('/a/b', '/**/d', { partial: true }) // true, might be /a/b/.../d minimatch('/x/y/z', '/a/**/z', { partial: true }) // false, because x !== a ``` +### windowsPathsNoEscape + +Use `\\` as a path separator _only_, and _never_ as an escape +character. If set, all `\\` characters are replaced with `/` in +the pattern. Note that this makes it **impossible** to match +against paths containing literal glob pattern characters, but +allows matching with patterns constructed using `path.join()` and +`path.resolve()` on Windows platforms, mimicking the (buggy!) +behavior of earlier versions on Windows. Please use with +caution, and be mindful of [the caveat about Windows +paths](#windows). + +For legacy reasons, this is also set if +`options.allowWindowsEscape` is set to the exact value `false`. + ## Comparisons to other fnmatch/glob implementations While strict compliance with the existing standards is a worthwhile diff --git a/minimatch.js b/minimatch.js index f3b491dd..71c96a1f 100644 --- a/minimatch.js +++ b/minimatch.js @@ -168,6 +168,11 @@ class Minimatch { this.options = options this.set = [] this.pattern = pattern + this.windowsPathsNoEscape = !!options.windowsPathsNoEscape || + options.allowWindowsEscape === false + if (this.windowsPathsNoEscape) { + this.pattern = this.pattern.replace(/\\/g, '/') + } this.regexp = null this.negate = false this.comment = false diff --git a/test/win-path-sep.js b/test/win-path-sep.js index 4b48d226..c4379fd1 100644 --- a/test/win-path-sep.js +++ b/test/win-path-sep.js @@ -39,3 +39,35 @@ t.test('posix default', t => { global.process = proc t.end() }) + +t.test('override with options', t => { + const mm = t.mock('../', { '../lib/path.js': {sep: '\\'}}) + + Object.defineProperty(process, 'platform', { + value: 'win32', + configurable: true, + enumerable: true, + writable: true, + }) + require('path').sep = '\\' + + t.equal(mm('c:\\foo\\bar', 'c:\\foo\\*', { + windowsPathsNoEscape: true, + }), true) + + t.equal(mm('c:\\foo\\bar', 'c:\\foo\\*', { + windowsPathsNoEscape: 'hamburger', + }), true) + + t.equal(mm('c:\\foo\\bar', 'c:\\foo\\*', { + allowWindowsEscape: false, + }), true) + + t.equal(mm('c:\\foo\\bar', 'c:\\foo\\*', {}), false) + + t.equal(mm('c:\\foo\\bar', 'c:\\foo\\*', { + allowWindowsEscape: null, + }), false) + + t.end() +})