paths-filter icon indicating copy to clipboard operation
paths-filter copied to clipboard

Excluding file via negation is not working as expected

Open Superskyyy opened this issue 3 years ago • 2 comments

For example below, I added a rootFiles and expect it to match nothing, however, it actually matches the root.tsx.

  test('matches all except tsx and less files (negate a group with or-ed parts)', () => {
    const yaml = `
    backend:
      - '!(**/*.tsx|**/*.less)'
    `
    const filter = new Filter(yaml)
    const tsxFiles = modified(['src/ui.tsx'])
    const lessFiles = modified(['src/ui.less'])
    const pyFiles = modified(['src/server.py'])
    const rootFiles = modified(['root.tsx'])

    const tsxMatch = filter.match(tsxFiles)
    const lessMatch = filter.match(lessFiles)
    const pyMatch = filter.match(pyFiles)
    const rootMatch = filter.match(rootFiles)

    expect(tsxMatch.backend).toEqual([])
    expect(lessMatch.backend).toEqual([])
    expect(pyMatch.backend).toEqual(pyFiles)
    expect(rootMatch.backend).toEqual([])
> 120 |     expect(rootMatch.backend).toEqual([])
      |                               ^
  121 | 
  122 |   })
  123 | 

  at Object.<anonymous> (__tests__/filter.test.ts:120:31)
  at processTicksAndRejections (node:internal/process/task_queues:96:5)

Superskyyy avatar May 03 '22 22:05 Superskyyy

We've used this, and it worked great for us, although it's become out of date recently due to no node 12 support on GHA.

https://github.com/AurorNZ/paths-filter

jbarmash avatar Oct 15 '22 20:10 jbarmash

@Superskyyy I think that your expectation expect(rootMatch.backend).toEqual([]) is incorrect.

According to picomatch documentation - the underlying matching library - a pattern like **/*.tsx requires at least 1 path separator, so in your example root.tsx doesn't match that part of the pattern and after negation actually matches the pattern.

If we try picomatch directly:

const picomatch = require('picomatch');
const pattern = '!(**/*.tsx|**/*.less)';
console.log(picomatch.isMatch('root.tsx', pattern));

returns true. If you want to ignore all *.tsx files regardless of their location, you should replace **/* with just ** in the pattern, see:

const picomatch = require('picomatch');
const pattern = '!(**.tsx|**/*.less)';  // new pattern
console.log(picomatch.isMatch('root.tsx', pattern));

returns false.

AndreyNautilus avatar Oct 26 '23 10:10 AndreyNautilus