Git Product home page Git Product logo

micromatch / micromatch Goto Github PK

View Code? Open in Web Editor NEW
2.6K 23.0 141.0 1.14 MB

Highly optimized wildcard and glob matching library. Faster, drop-in replacement to minimatch and multimatch. Used by square, webpack, babel core, yarn, jest, ract-native, taro, bulma, browser-sync, stylelint, nyc, ava, and many others! Follow micromatch's author: https://github.com/jonschlinkert

Home Page: https://github.com/micromatch

License: MIT License

JavaScript 100.00%
glob glob-pattern glob-matching matcher bash javascript multimatch minimatch regex regular-expression extglob globbing wildmat node-glob globby node micromatch wildcard extended-glob tidelift

micromatch's Issues

Update is-glob

I just updated my glob-parent dependency in glob-stream and was warned about micromatch requiring a different version. Thought I'd give the heads up.

bug when absolute path and dot option true/false

var path = require('path')
var absolute = true

var filepath = absolute ? path.resolve('.git') : '.git'
var pattern = absolute ? path.resolve('**') : '**'

console.log(filepath)
console.log(pattern)

var matches = mm(filepath, pattern, {dot: false})
var ismatch = mm.isMatch(filepath, pattern, {dot: false})
var reEnabled = mm.makeRe(filepath, {dot: true})
var reDisabled = mm.makeRe(filepath, {dot: false})

console.log(matches) // => [ '/home/charlike/dev/final/glob-fs/.git' ]
console.log(ismatch) // => true
console.log(reEnabled.test(filepath)) // => true
console.log(reDisabled.test(filepath)) // => true
console.log(reEnabled)  // => /^(?:\/home\/charlike\/dev\/final\/glob-fs\/\.git)$/
console.log(reDisabled) // => /^(?:\/home\/charlike\/dev\/final\/glob-fs\/\.git)$/

Try out to change absolute to false and you get empty array. Which is the correct behaving when dot: false. But when absolute path and absolute pattern is passed it find match when dot: false.

seeing utils.isGlob error with versions of micromatch > 2.3.1

Note, this error does not occur with 2.1.6, but has occurred since 2.3.1:

TypeError: lazy-cache utils.isGlob is not a function /Users/benjamincoe/bcoe/nyc/node_modules/micromatch/node_modules/lazy-cache/index.js
    at matcher (/Users/benjamincoe/bcoe/nyc/node_modules/micromatch/index.js:301:14)
    at Function.any (/Users/benjamincoe/bcoe/nyc/node_modules/micromatch/index.js:239:19)
    at NYC.shouldInstrumentFile (/Users/benjamincoe/bcoe/nyc/index.js:136:25)
    at NYC.addFile (/Users/benjamincoe/bcoe/nyc/index.js:98:25)
    at Object.defaultHook (/Users/benjamincoe/bcoe/nyc/index.js:163:21)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Module.require (module.js:365:17)
    at require (module.js:384:17)
    at Function.getter (/Users/benjamincoe/bcoe/nyc/node_modules/micromatch/node_modules/lazy-cache/index.js:32:31)

Directory begin with dot

Hi !

Strange behavior since 2.2.0 :

> mm.isMatch('.tmp/scripts/app.js', '.tmp/scripts/**/*.js');
false

in 2.1.6 :

> mm.isMatch('.tmp/scripts/app.js', '.tmp/scripts/**/*.js');
true

Is that normal ?

Thx

array of globs for matcher

Public api should also accept precompiled array of globs for matcher like filter. API parts should be similar, I think.

false on regex group matching

with is-match

var matcher = require('is-match')
var isMatch = matcher(['123.[71-79].34.*'])

console.log(isMatch('123.77.34.89'))
//=> false

[:punct:] expanded incorrectly

[:punct:] is changed to [!"#$%&\'()\\*+,-./:;<=>?@[\\]^_{|}~][here](https://github.com/jonschlinkert/micromatch/blob/17f06276a9a1fc8858582612d73aec5abf8744c6/lib/expand.js#L117) and because it starts with[!` it's changed to the negated version right after. I suppose the most simple fix would be changing order of the characters in the regex class.

globstar and trailing slash

From #62

var micromatch = require('micromatch')
var isMatch = micromatch.matcher('foo/bar/**')
console.log(isMatch('foo/bar')) // => false, i think it make sense to pass?
console.log(isMatch('foo/bar/')) // => true
console.log(isMatch('foo/bar/baz')) // => true
console.log(isMatch('foo/bar/baz/fez')) // => true
console.log(isMatch('foo/bar/baz/qux.js')) // => true

If that's correct behaving, okey, but you are forced to do some hacks like #62 (comment) and it not make sense for me.

edit: and ** means anything or empty - same as single *. so basically if it make sense to match with trailing slash it make sense to match without it, because it is absolutely the same - in anyway it is the dir.

Issue with wildcard + negated extglob

Using v2.1.6

> mm.isMatch('src/a/b/c.js', 'src/**/*!(_test).js')
false
> mm.isMatch('src/a/b/c_test.js', 'src/**/*!(_test).js')
false

Using master branch

> mm.isMatch('src/a/b/c.js', 'src/**/*!(_test).js')
true
> mm.isMatch('src/a/b/c_test.js', 'src/**/*!(_test).js')
true

Specifying extglob: true or extglob: false does not appear to have any impact. When the * is removed before the ! it behaves as I'd expect.

paulmillr/chokidar#58

possibility `.filter` to accept array glob pattern

Like...

[
  'fs-readdir-callback-api.js',
  'fs-readdir-stream-api.js',
  'glob-stream.js',
  'readdirp-callback-api.js',
  'readdirp-stream-api.js',
  'recursive-readdir.js'
].filter(micromatch.filter(['*', '!*api*']))
//=> ['glob-stream.js', 'recursive-readdir.js']

Use case if .filter accepts array
this part of recursive-readdir package would become something like this

var ignoreOpts = {dot: true, matchBase: true};
var nonIgnores = ignores.filter(function(ignore) {
  return ignore.chatAt(0) !== '!';
})
var ignored = map(nonIgnores, function(ignore) {
  return '!' + ignore;
});
ignores = [].concat([ignores, ignored])
var ignoreFilter = micromatch.filter(ignores, ignoreOpts)

files.filter(ignoreFilter).forEach(function (file) {
  // ... another code below

The glob string */*/** fails to match a lot of things

const micromatch = require('micromatch');

// create a matcher that should return true for any
// file that's inside at least two nested directories...
const match = micromatch.matcher('*/*/**');

// it's correct for these paths:
match('a/b.txt'); // false
match('a/b/c.txt'); // true

// but it stops matching if you add more levels, despite double-star:
match('a/b/c/d.txt'); // false (expected true)
match('a/b/c/d/e.txt'); // false (expected true)

Live demo of this bug on Tonic

re-organize tests

unit tests and file names need to be organized differently to make it easier to test for regressions and new features.

2.3.6 housekeeping

for starters...

  • replace gulp-jshint with gulp-eslint
  • lint (I expect this to result in a bunch of small changes since we'll be using a much more stringent linting config)

I'm planning on doing this in the next patch. anything to add @es128?

** sometimes matches dotfiles

From #62:

mm.isMatch('/aaa/bbb/.git', '/aaa/bbb/**'); // => true; should be false
mm.isMatch('aaa/bbb/.git', 'aaa/bbb/**'); // => true; should be false
mm.isMatch('/aaa/bbb/ccc/.git', '/aaa/bbb/**'); // => false; correct

globstar

AFAIK, the double star should only match multiple directories if it' the only thing in a path part, e.g., a/**/b, but not a/b**.

In micromatch, it seems it can be followed by other characters:

mm.isMatch('a/b/c', 'a/b**'); // => returns false
mm.isMatch('a/c/b', 'a/**b'); // => returns true (maybe a bug?)

Is this intentional?

Problems with $

> mm.isMatch('$', '$')
true
> mm.isMatch('$/foo', '$/*')
false
> mm.isMatch('a/foo', 'a/*')
true
> mm.isMatch('$/foo', '$/*')
false
> mm.isMatch('$foo/foo', '$foo/*')
false
> mm.isMatch('foo$/foo', 'foo$/*')
false
> mm.isMatch('foo/foo', 'foo/*')
true

paulmillr/chokidar#357

Whitespace in path

Hi, I'm trying to match files using the following pattern:

require('micromatch')('/Users/tobiasreich/Sites/aaa/bbb/ccc 2016/src/de.ejs', [
    '/Users/tobiasreich/Sites/aaa/bbb/ccc 2016/src/**/[^_]*.{html,ejs}'
]) // => []

micromatch sadly returns an empty array, which is not what I expected. After several experiments I figured out that the whitespace between "ccc" and "2016" might be the reason for it.

require('micromatch')('/Users/tobiasreich/Sites/aaa/bbb/ccc2016/src/de.ejs', [
    '/Users/tobiasreich/Sites/aaa/bbb/ccc2016/src/**/[^_]*.{html,ejs}'
]) // => ['/Users/tobiasreich/Sites/aaa/bbb/ccc2016/src/de.ejs']

Is this a problem of the pattern I'm using or an issue of micromatch? How should I deal with spaces in paths?

Node.js Version: 6.2
micromatch Version: 2.3.8

Partial wildcard bug (without globstar)

Uncovered by @tunnckoCore in #15 (thank you). Opening a new issue to track resolution.

console.log(micromatch.isMatch('a/z.js', 'a/z*.js'));
//=> should be true
console.log(micromatch(paths, '*/z*.js'));
//=> should be [ 'a/z.js' ]
// multimatch

console.log(multimatch(paths, '*/z*.js'));
//=> [ 'a/z.js' ]

path variables

Consider supporting bash-like path variables, ex. ${foo}. Should be easy to do since the syntax is exactly the same as es6 variables.

Issue when using negations against /'s

This might just be me being stupid, but I want to check :)

Can someone please clarify the state of these two globs? Afaik they should both match?

# matches
mm.any('/target/build', ['/target/!(dist)'])

# doesn't match
mm.any('/target/build/classes', ['/target/!(dist)'])

I'm not too familiar with globs so maybe I'm missing something. I guess the potential to have a /... after is throwing it off?

mm.any('/target/build/classes', ['!/target/dist']) matches too, but in my use case the /target/ prefix might be changing, so I can't just hardcode that section of the pattern.

Thanks in advance! Great library, very nice to use.

problem with "logical OR" or problem in my mind, lol?

I use makeRe to generate regex based on glob pattern to test against some filepath.

examples

var expected = false;
var options = {};
var pattern = 'maiden/{**/*.,*.}';
var re = mm.makeRe(pattern, options);
console.log(re.test('maiden/code'));
//=> true

isMatch()

var expected = false;
var options = {};
var pattern = 'maiden/{**/*.,*.}';
var match = mm.isMatch('maiden/code', pattern, options);
console.log(match);
//=> true

micromatch()

var expected = [];
var options = {};
var pattern = 'maiden/{**/*.,*.}';
var match = mm('maiden/code', pattern, options);
console.log(match);
//=> ['maiden/code']

I think its logical to return true only if there no dots in the pattern, ie 'maiden/{**/*,*}'

What is the difference between matcher and filter?

This might be a documentation issue, or maybe I'm being stupid.

The readme says that .matcher(pattern) gets you a function that you can use to match paths. I'm assuming this means it returns true/false, in which case it sounds like it could be used as an array filter function.

But then there seems to be another method for this exact purpose, .filter(): "Returns a function that can be passed to Array#filter()." I don't get it. Can't the returned function from .matcher be used in this way?

What's the difference?

make patterns the first arg?

This is a major breaking change, and it's probably a bad idea given that minimatch has gotten everyone used to passing patterns as the second arg, but I've always strongly disliked it and found it confusing.

I'm curious if anyone else agrees with this.

This is the current signature, with pattern(s) usually the second arg:

mm(['a/b/a.md', 'a/b/b.md', 'a/b/c.md', 'a/b/d.md', ], '**/*.md');

I think it makes more sense like this:

mm('**/*.md', ['a/b/a.md', 'a/b/b.md', 'a/b/c.md', 'a/b/d.md']);

This signature makes using the lib more consistent when arguments are partially applied to create matching functions, like var isMatch = matcher('foo/*.md'); which returns a function that could be passed to Array#filter for example.

Also, passing the pattern first feels more natural when regex is used instead of a glob pattern.

mm(/\.md$/, ['a/b/a.md', 'a/b/b.md', 'a/b/c.md', 'a/b/d.md']);

Release 2.2.0

Just trying to gather all the outstanding points discussed recently to be resolved prior to release. Anything is still open to discussion if there remains any disagreement about any of these points.

@jonschlinkert In the future if you want to do your changes in branches/PRs I'd be happy to review and I think it would make it easier to keep all feedback and resolution organized.

  • Ensure extglob, braces, and brackets parsing are enabled by default
  • Drop the options as above in favor of the no* alternatives
  • Support nobrace option as alias for nobraces for minimatch parity
  • Tests to ensure both nobrace and nobraces remain supported at least until a major version bump
  • Ensure readme documentation accurately reflects all of the above
  • Fix readme anchor links
  • Update benchmarks & browser build

how to get the contains matched string

The current contains method just returns true or false, is there anyway to get the contains string.

For example:

// Old style
mm.contains('a/b/c', 'a/*');
//=> true

// New Style
mm.contains('a/b/c', 'a/*');
//=> a/b

In my case, I just want to replace the matched string with empty

dot not properly escaped in expandFilename

These should return false

> mm.isMatch('zzjs', 'z*.js')
true
> mm.isMatch('zzjs', '*z.js')
true

With a directory in the pattern, it behaves correctly because the dot gets escaped

> mm.isMatch('a/zzjs', 'a/*z.js')
false
> mm.isMatch('a/zzjs', 'a/z*.js')
false

Dot directory and {* /} combination is not working

Dot directory and {* /} combination is not working

Start dot directory, failed.

> mm.isMatch('.a/xyz.md', '.a/{,*/}xyz.md')
false
> mm.isMatch('.a/xyz.md', '.a/**/xyz.md')
false

Start not dot directory, success.

> mm.isMatch('a/xyz.md', 'a/{,*/}xyz.md')
true
> mm.isMatch('a/xyz.md', 'a/**/xyz.md')
true

problem with re-include, excluded path

Because I still working on glob-fs idea :D lol
Actually it works on 80% of the common usage of gulp/glob-stream, fails only on complex fixtures, or no logical tests (look at you glob-stream, nah.. it have very very weird tests).
Btw, talking about that, can you answer me why is needed to ignore negate glob if it is first in given patterns?!
No logic for me... nor of matching libs (micromatch/minimatch/node-glob) have this behaving.. lol.

On topic

var micromatch = require('micromatch')
var multimatch = require('multimatch')

var paths = [
  'foo/',
  'foo/bar.js',
  'foo/bar.md',
  'foo/bar.txt',
  'foo/bar.hbs',
  'foo/bar.json',
  'foo/bar.coffee',
  'foo/bar/',
  'foo/bar/bar.js',
  'foo/bar/bar.md',
  'foo/bar/bar.txt',
  'foo/bar/bar.hbs',
  'foo/bar/bar.json',
  'foo/bar/bar.coffee',
];

var patterns = [
  'foo/**',
  '!foo/',
  '!foo/bar/',
  '!foo/bar/*.{j*,txt,hbs}',
  'foo/bar/*.json',
];

var res = micromatch(paths, patterns);

console.log(res, res.length);

micromatch, note there foo/bar/bar.json missing

[ 'foo/bar.js',
  'foo/bar.md',
  'foo/bar.txt',
  'foo/bar.hbs',
  'foo/bar.json',
  'foo/bar.coffee',
  'foo/bar/bar.md',
  'foo/bar/bar.coffee' ] 8

multimatch, all is okey

[ 'foo/bar.js',
  'foo/bar.md',
  'foo/bar.txt',
  'foo/bar.hbs',
  'foo/bar.json',
  'foo/bar.coffee',
  'foo/bar/bar.md',
  'foo/bar/bar.coffee',
  'foo/bar/bar.json' ] 9

cwd option

Do you have plans to support a cwd option?

Otherwise it is a bit unclear where the fs lookup is performed.

Partial matching

When implementing a glob-walker, it'd be useful if we were able to tell that files in a specific directory will never match the pattern, without trying to match all of them.

E.g., with a pattern aaa/{bbb,ccc}/**/*.js, we could immediately discard folder aaa/ddd, without listing and matching everything inside, which would greatly reduce the number of fs operations.

I tried to implement a flag mightMatch, which would change the behavior to returning true if filepath matches the beginning of the pattern and false if it doesn't (for aaa/bbb the generated RegExp would be something like /^(?:\/$|(?:aaa(\/bbb)?)?)$/), but I couldn't get it working in all edge cases.

Is there any chance you could add such function, or at least suggest where would be the right place to implement this?

Array with negation pattern

As you noted in level-glob#1 (thanks!), there's a possible bug (I'm not sure either) when using multiple patterns and negation. I did some tests with both 1.0.1 and 1.4.2, and it comes down to the following. These two lines produce different results:

var mm = require('micromatch');
console.log(mm.match(['a.md', 'b.js'], ['!*.md']));
console.log(mm.match(['a.md', 'b.js'], '!*.md'));

The first matches nothing, the second matches b.js. Is this expected behavior?

What's the purpose, idea behind?

Is the purpose is to be completely compatible with minimatch and pass it's tests?

Because I think minimatch support too much cases for one simple usage like glob filepaths. I fork the repo and made some basic implementation and tests.

It would be great if you come with more test cases. :)

Double globstar bug

From paulmillr/chokidar#283

> mm.isMatch('markup/modules/exampleModule/assets/image.png', 'markup/modules/**/assets/**/*.*')
false
// should be true

// these are ok:
> mm.isMatch('markup/modules/exampleModule/assets/subDir/image.png', 'markup/modules/**/assets/**/*.*')
true
> mm.isMatch('markup/modules/exampleModule/assets/subDir/subDir/image.png', 'markup/modules/**/assets/**/*.*')
true

nodupes option not work as expected?

Heya, not sure enough be I have one snippet here...

var files = [
  '.editorconfig',
  '.git',
  '.gitignore',
  '.nyc_output',
  '.travis.yml',
  '.verb.md',
  'CHANGELOG.md',
  'CONTRIBUTING.md',
  'LICENSE',
  'coverage',
  'example.js',
  'example.md',
  'example.css',
  'index.js',
  'node_modules',
  'package.json',
  'test.js',
  'utils.js'
]

console.log(micromatch(files, ['example.*', '*.js'], {
  nodupes: true
}))

result (outputs example.js twice?)

[ 'example.js',
  'example.md',
  'example.css',
  'example.js',
  'index.js',
  'test.js',
  'utils.js' ]

problem (not so) matching urls

I realize that it is because of filepaths globbing idea, but it's uncomfortable when trying to match urls.

var matcher = require('is-match')

matcher('https://github.com/*')('https://github.com/tunnckoCore')
//=> false

matcher('https://github.com**/**')('https://github.com/tunnckoCore')
//=> false

matcher('https://github.co**/**')('https://github.com/tunnckoCore')
//=> false

matcher('https://github.com/**/**')('https://github.com/tunnckoCore')
//=> false

matcher('https://github.com/**/*')('https://github.com/tunnckoCore')
//=> false

matcher('http*')('https://foo.com')
//=> false

matcher('http**/*')('https://foo.com')
//=> false

matcher('http*/**')('https://foo.com')
//=> true

matcher('http**/**')('https://foo.com')
//=> true

using chorks/is-match#master (waiting merge PR) which uses micromatch v2.1.6

Maybe Im missing some option? Or we should add some option? :D

regression v2.2.0

Possible regression with default micromatch options. #27 (comment)

The first two examples don't match anymore after upgrading to v2.2.0.
Looks like it doesn't match when pattern starts with globstar (**) and no slashes (/) are present in the pattern.

v2.2.0

micromatch(['/api/foo/bar.html'], '**.*')          //  regression?
//=> []

micromatch(['/api/foo/bar.html'], '**.html')       //  regression?
//=> []

micromatch(['/api/foo/bar.html'], '/**.*')
//=> ['/api/foo/bar.html']

micromatch(['/api/foo/bar.html'], '/**.html')
//=> ['/api/foo/bar.html']

micromatch(['/api/foo/bar.html'], '/**/*.*')
//=> ['/api/foo/bar.html']

v2.1.6

micromatch(['/api/foo/bar.html'], '**.*')
//=> ['/api/foo/bar.html']

micromatch(['/api/foo/bar.html'], '**.html')
//=> ['/api/foo/bar.html']

micromatch(['/api/foo/bar.html'], '/**.*')
//=> ['/api/foo/bar.html']

micromatch(['/api/foo/bar.html'], '/**.html')
//=> ['/api/foo/bar.html']

micromatch(['/api/foo/bar.html'], '/**/*.*')
//=> ['/api/foo/bar.html']

Bug with partial wildcards

> mm.isMatch('../test-fixtures/add.txt', '../test-fixtures/**/a*.txt')
true
> mm.isMatch('../test-fixtures/add.txt', '../test-*/**/a*.txt')
false
> mm.isMatch('../test-fixtures/subdir/subsub/a.txt', '../test-*/**/a*.txt')
false
> mm.isMatch('../test-fixtures/subdir/subsub/ab.txt', '../test-*/**/a*.txt')
true

Realized this is the cause of a few newly failing tests in chokidar

Travis Error: Failed resolving git HEAD (https://github.com/jonschlinkert/micromatch

Just got this error in our Travis build, it's a subdependency (karma - anymatch - micromatch )

npm ERR! Failed resolving git HEAD (https://github.com/jonschlinkert/micromatch) fatal: ambiguous argument '2.3.0': unknown revision or path not in the working tree.

npm ERR! Failed resolving git HEAD (https://github.com/jonschlinkert/micromatch) Use '--' to separate paths from revisions, like this:

npm ERR! Failed resolving git HEAD (https://github.com/jonschlinkert/micromatch) 'git <command> [<revision>...] -- [<file>...]'

npm ERR! Failed resolving git HEAD (https://github.com/jonschlinkert/micromatch) 

This issue probably do not belong here, but I put it here for others to be aware of the issue

Could this be a version mismatch at your end, or is this a result of bad dep version range in a dependency?

Double globstar does not play well with backslashes

This seems to be a bug.

mm('/user.js', '**.js')
// expected => true
// got      => false

ย 

Everything works great if a / is nowhere in the string; as seen below.

mm('user.js', '**.js')
// expected => true
// got      => true

ย 

Using **/*.js instead is a workaround.

mm('/user.js', '**/*.js')
// expected => true
// got      => true

mm('user.js', '**/*.js')
// expected => true
// got      => true

ย 

NodeJS v0.12.4
micromatch v2.2.0

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.