From 7505a40ac4f1f36aa56e9d937432bb3bdabf7328 Mon Sep 17 00:00:00 2001 From: Richard Lau Date: Thu, 23 Jul 2020 14:54:55 -0400 Subject: [PATCH] Check find binary supports the `-iname` parameter The `-iname` parameter is a non-POSIX extension and may not be supported by a POSIX compliant find binary. Add a check that the parameter is supported when determining whether to use the native find binary. --- CHANGELOG.md | 1 + .../src/crawlers/__tests__/node.test.js | 39 +++++++++++++++++++ packages/jest-haste-map/src/crawlers/node.ts | 9 ++++- 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d58d366357f..71dd13a5f1fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - `[expect]` Match symbols and bigints in `any()` ([#10223](https://github.com/facebook/jest/pull/10223)) - `[jest-changed-files]` Use `git diff` instead of `git log` for `--changedSince` ([#10155](https://github.com/facebook/jest/pull/10155)) - `[jest-console]` Add missing console.timeLog for compatability with Node ([#10209](https://github.com/facebook/jest/pull/10209)) +- `[jest-haste-map] `Check find binary supports the `-iname` parameter ([#10308](https://github.com/facebook/jest/pull/10308)) - `[jest-snapshot]` Strip added indentation for inline error snapshots ([#10217](https://github.com/facebook/jest/pull/10217)) ### Chore & Maintenance diff --git a/packages/jest-haste-map/src/crawlers/__tests__/node.test.js b/packages/jest-haste-map/src/crawlers/__tests__/node.test.js index c972f0da6dd1..ab3b894d796e 100644 --- a/packages/jest-haste-map/src/crawlers/__tests__/node.test.js +++ b/packages/jest-haste-map/src/crawlers/__tests__/node.test.js @@ -14,6 +14,11 @@ jest.mock('child_process', () => ({ spawn: jest.fn((cmd, args) => { let closeCallback; return { + on: jest.fn().mockImplementation((event, callback) => { + if (event === 'exit') { + callback(mockSpawnExit, null); + } + }), stdout: { on: jest.fn().mockImplementation((event, callback) => { if (event === 'data') { @@ -131,6 +136,7 @@ const createMap = obj => new Map(Object.keys(obj).map(key => [key, obj[key]])); const rootDir = '/project'; let mockResponse; +let mockSpawnExit; let nodeCrawl; let childProcess; @@ -148,6 +154,8 @@ describe('node crawler', () => { '/project/fruits/strawberry.js', '/project/fruits/tomato.js', ].join('\n'); + + mockSpawnExit = 0; }); it('crawls for files based on patterns', () => { @@ -293,6 +301,37 @@ describe('node crawler', () => { }); }); + it('uses node fs APIs on Unix based OS with incompatible find binary', () => { + process.platform = 'linux'; + mockResponse = ''; + mockSpawnExit = 1; + childProcess = require('child_process'); + const which = require('which'); + which.mockReturnValueOnce(Promise.resolve('/mypath/find')); + + nodeCrawl = require('../node'); + + return nodeCrawl({ + data: { + files: new Map(), + }, + extensions: ['js'], + ignore: pearMatcher, + rootDir, + roots: ['/project/fruits'], + }).then(({hasteMap, removedFiles}) => { + expect(childProcess.spawn).lastCalledWith('find', ['.', '-iname', "''"]); + expect(hasteMap.files).toEqual( + createMap({ + 'fruits/directory/strawberry.js': ['', 33, 42, 0, '', null], + 'fruits/tomato.js': ['', 32, 42, 0, '', null], + }), + ); + expect(removedFiles).toEqual(new Map()); + expect(which).toBeCalledWith('find'); + }); + }); + it('uses node fs APIs on Unix based OS without find binary', () => { process.platform = 'linux'; const which = require('which'); diff --git a/packages/jest-haste-map/src/crawlers/node.ts b/packages/jest-haste-map/src/crawlers/node.ts index 0266816d91fb..456ad922448e 100644 --- a/packages/jest-haste-map/src/crawlers/node.ts +++ b/packages/jest-haste-map/src/crawlers/node.ts @@ -31,7 +31,14 @@ async function hasNativeFindSupport( try { await which('find'); - return true; + return await new Promise(resolve => { + // Check the find binary supports the non-POSIX -iname parameter. + const args = ['.', '-iname', "''"]; + const child = spawn('find', args); + child.on('exit', code => { + resolve(code == 0); + }); + }); } catch { return false; }