picomatch icon indicating copy to clipboard operation
picomatch copied to clipboard

It seems like ./ breaks matching.

Open sixcircuit opened this issue 3 years ago • 4 comments

I feel like I must be doing something wrong, or misunderstanding how the library works, but it seems like the first one (with leading ./) should be true as well. I'm on version 2.2.2.

Is this a bug or am I missing something?

picomatch.isMatch("./a/b.js", "./a/*.js"); // false picomatch.isMatch("/a/b.js", "/a/*.js"); // true

Thanks for the awesome library!

sixcircuit avatar Mar 04 '21 02:03 sixcircuit

If that doesn't match that's a bug. We've covered this more times than I can count, I don't know why that doesn't match, so there must be a regression somewhere. I'll look into it.

However, FWIW we try to follow bash conventions, and in general, paths that are prefixed with ./ are not "real" paths, meaning you won't ever receive a path with ./ from the file system. So I'm not sure why so many people try to match ./, or if that's something you're actually trying to match or if it's just a contrived pattern and you're curious. It would help to understand this more so I can anticipate the scenarios where we'd need to match paths with this prefix consistently.

jonschlinkert avatar May 22 '21 18:05 jonschlinkert

I'm looking into this now, but in the meantime I recommend not adding ./ in front of the path to be matched. If you're doing some kind of parsing and trying to match paths from import or require statements (which is the only place I can think of where paths need this prefix), then just remove the ./ before matching.

jonschlinkert avatar May 22 '21 18:05 jonschlinkert

Yeah. You're right. The fact that this didn't work made me rethink how I handle paths in my whole application. Specifically that ./ is unnecessary, because if a path is missing the forward slash (isn't absolute) it's necessarily relative to the current working directory. Missing the forward slash is the same thing as ./ I can't believe it's taken me 20 years to realize this. You use it a lot in bash to get a local command to run, ./command So I think we're just used to referring to the current working directory as ./ And you're right, require statements as well. It's wrong, but common. I mean, I guess they're both valid. And I think the match should work, but it's not a problem for me anymore. I say all this just in case someone else runs across this issue. I think the solution is never use the ./ in path representations in your applications, and if you have to pass a relative path to require, add the ./ to it when you pass it in. Thanks again.

sixcircuit avatar May 22 '21 19:05 sixcircuit

I can't believe it's taken me 20 years to realize this

ha, well you're definitely not alone. I did the same and I didn't really think about it until I had to solve issues related to it with matching libs like picomatch. I also stopped using ./ everywhere as well, with the exception of necessary require/import statements. I figure it's two characters that don't need to be parsed and removed from paths, so that saves a tiny infinitesimal amount of time too lol.

jonschlinkert avatar May 22 '21 21:05 jonschlinkert

I ran into this bug too.

Is this the proposed workaround? (taken from the readme)

const format = str => str.replace(/^\.\//, '');
const isMatch = picomatch('foo/*.js', { format });

jakobrosenberg avatar Aug 17 '22 07:08 jakobrosenberg

Is this the proposed workaround? (taken from the readme)

I believe that should work. But it might be easier to just do something like this:

const isMatch = picomatch('foo/*.js', { format });
const removeLeadingSlash = str => str.startsWith('./') ? str.slice(2) : str;
const input = './foo/bar.js';

console.log(isMatch(removeLeadingSlash(input)));

jonschlinkert avatar Aug 17 '22 17:08 jonschlinkert

I'm going to go ahead and close this based on age. We can reopen if necessary. thx

jonschlinkert avatar Aug 17 '22 17:08 jonschlinkert