Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(haste-map): watchman crawler now includes dotfiles #10075

Merged
merged 8 commits into from Jul 30, 2020
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -2,6 +2,7 @@

### Features

- `[jest-haste-map]` Watchman crawler now includes dotfiles ([#10075](https://github.com/facebook/jest/pull/10075))
- `[jest-worker]` Added support for workers to send custom messages to parent in jest-worker ([#10293](https://github.com/facebook/jest/pull/10293))
- `[pretty-format]` Added support for serializing custom elements (web components) ([#10217](https://github.com/facebook/jest/pull/10237))

Expand Down
1 change: 1 addition & 0 deletions jest.config.js
Expand Up @@ -49,6 +49,7 @@ module.exports = {
'/packages/jest-cli/src/init/__tests__/fixtures/',
'/packages/jest-haste-map/src/__tests__/haste_impl.js',
'/packages/jest-haste-map/src/__tests__/dependencyExtractor.js',
'/packages/jest-haste-map/src/__tests__/test_dotfiles_root/',
'/packages/jest-resolve-dependencies/src/__tests__/__fixtures__/',
'/packages/jest-runtime/src/__tests__/defaultResolver.js',
'/packages/jest-runtime/src/__tests__/module_dir/',
Expand Down
1 change: 1 addition & 0 deletions packages/jest-haste-map/package.json
Expand Up @@ -16,6 +16,7 @@
"anymatch": "^3.0.3",
"fb-watchman": "^2.0.0",
"graceful-fs": "^4.2.4",
"jest-regex-util": "^26.0.0",
"jest-serializer": "^26.1.0",
"jest-util": "^26.1.0",
"jest-worker": "^26.1.0",
Expand Down
48 changes: 48 additions & 0 deletions packages/jest-haste-map/src/__tests__/includes_dotfiles.test.ts
@@ -0,0 +1,48 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import path from 'path';
import HasteMap from '../index';

const rootDir = path.join(__dirname, './test_dotfiles_root');

const commonOptions = {
extensions: ['js'],
maxWorkers: 1,
platforms: [],
resetCache: true,
retainAllFiles: true,
rootDir,
roots: [rootDir],
};

test('watchman crawler and node crawler both include dotfiles', async () => {
const hasteMapWithWatchman = new HasteMap({
...commonOptions,
name: 'withWatchman',
useWatchman: true,
});

const hasteMapWithNode = new HasteMap({
...commonOptions,
name: 'withNode',
useWatchman: false,
});

const [builtHasteMapWithWatchman, builtHasteMapWithNode] = await Promise.all([
hasteMapWithWatchman.build(),
hasteMapWithNode.build(),
]);

expect(
builtHasteMapWithWatchman.hasteFS.matchFiles('.eslintrc.js'),
).toHaveLength(1);

expect(builtHasteMapWithWatchman.hasteFS.getAllFiles().sort()).toEqual(
builtHasteMapWithNode.hasteFS.getAllFiles().sort(),
);
});
39 changes: 39 additions & 0 deletions packages/jest-haste-map/src/__tests__/index.test.js
Expand Up @@ -294,6 +294,45 @@ describe('HasteMap', () => {
});
});

it('ignores vcs directories without ignore pattern', () => {
mockFs['/project/fruits/.git/fruit-history.js'] = `
// test
`;
return new HasteMap(defaultConfig).build().then(({hasteFS}) => {
expect(hasteFS.matchFiles('.git')).toEqual([]);
});
});

it('ignores vcs directories with ignore pattern regex', () => {
const config = {...defaultConfig, ignorePattern: /Kiwi/};
mockFs['/project/fruits/Kiwi.js'] = `
// Kiwi!
`;

mockFs['/project/fruits/.git/fruit-history.js'] = `
// test
`;
return new HasteMap(config).build().then(({hasteFS}) => {
expect(hasteFS.matchFiles(/Kiwi/)).toEqual([]);
expect(hasteFS.matchFiles('.git')).toEqual([]);
});
});

it('ignores vcs directories with ignore pattern function', () => {
const config = {...defaultConfig, ignorePattern: f => /Kiwi/.test(f)};
mockFs['/project/fruits/Kiwi.js'] = `
// Kiwi!
`;

mockFs['/project/fruits/.git/fruit-history.js'] = `
// test
`;
return new HasteMap(config).build().then(({hasteFS}) => {
expect(hasteFS.matchFiles(/Kiwi/)).toEqual([]);
expect(hasteFS.matchFiles('.git')).toEqual([]);
});
});

it('builds a haste map on a fresh cache', () => {
// Include these files in the map
mockFs['/project/fruits/node_modules/react/React.js'] = `
Expand Down
@@ -0,0 +1,6 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
@@ -0,0 +1,6 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
2 changes: 1 addition & 1 deletion packages/jest-haste-map/src/crawlers/watchman.ts
Expand Up @@ -126,7 +126,7 @@ export = async function watchmanCrawl(
? // Use the `since` generator if we have a clock available
{expression, fields, since: clocks.get(relativeRoot)}
: // Otherwise use the `glob` filter
{expression, fields, glob};
{expression, fields, glob, glob_includedotfiles: true};
SimenB marked this conversation as resolved.
Show resolved Hide resolved

const response = await cmd('query', root, query);

Expand Down
32 changes: 25 additions & 7 deletions packages/jest-haste-map/src/index.ts
Expand Up @@ -15,6 +15,7 @@ import {NodeWatcher, Watcher as SaneWatcher} from 'sane';
import type {Config} from '@jest/types';
import serializer from 'jest-serializer';
import Worker from 'jest-worker';
import {escapePathForRegex} from 'jest-regex-util';
import {getSha1, worker} from './worker';
import getMockName from './getMockName';
import getPlatformExtension from './lib/getPlatformExtension';
Expand Down Expand Up @@ -113,6 +114,9 @@ const CHANGE_INTERVAL = 30;
const MAX_WAIT_TIME = 240000;
const NODE_MODULES = path.sep + 'node_modules' + path.sep;
const PACKAGE_JSON = path.sep + 'package.json';
const VCS_DIRECTORIES = ['.git', '.hg']
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

svn?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

meh, I have no idea how it works, and people can open a PR if needed. Should be a simple fix for anyone knowing how subversion works. And we only ship mercurial and git support anyways

.map(vcs => escapePathForRegex(path.sep + vcs + path.sep))
.join('|');

// TypeScript doesn't like us importing from outside `rootDir`, but it doesn't
// understand `require`.
Expand Down Expand Up @@ -233,7 +237,6 @@ class HasteMap extends EventEmitter {
extensions: options.extensions,
forceNodeFilesystemAPI: !!options.forceNodeFilesystemAPI,
hasteImplModulePath: options.hasteImplModulePath,
ignorePattern: options.ignorePattern,
maxWorkers: options.maxWorkers,
mocksPattern: options.mocksPattern
? new RegExp(options.mocksPattern)
Expand All @@ -250,11 +253,26 @@ class HasteMap extends EventEmitter {
watch: !!options.watch,
};
this._console = options.console || global.console;
if (options.ignorePattern && !(options.ignorePattern instanceof RegExp)) {
this._console.warn(
'jest-haste-map: the `ignorePattern` options as a function is being ' +
'deprecated. Provide a RegExp instead. See https://github.com/facebook/jest/pull/4063.',
);

if (options.ignorePattern) {
if (options.ignorePattern instanceof RegExp) {
this._options.ignorePattern = new RegExp(
options.ignorePattern.source.concat('|' + VCS_DIRECTORIES),
SimenB marked this conversation as resolved.
Show resolved Hide resolved
options.ignorePattern.flags,
);
} else {
const ignorePattern = options.ignorePattern;
const vcsIgnoreRegExp = new RegExp(VCS_DIRECTORIES);
this._options.ignorePattern = (filePath: string) =>
vcsIgnoreRegExp.test(filePath) || ignorePattern(filePath);

this._console.warn(
'jest-haste-map: the `ignorePattern` options as a function is being ' +
'deprecated. Provide a RegExp instead. See https://github.com/facebook/jest/pull/4063.',
);
}
} else {
this._options.ignorePattern = new RegExp(VCS_DIRECTORIES);
}

const rootDirHash = createHash('md5').update(options.rootDir).digest('hex');
Expand Down Expand Up @@ -790,7 +808,7 @@ class HasteMap extends EventEmitter {
const createWatcher = (root: Config.Path): Promise<Watcher> => {
// @ts-expect-error: TODO how? "Cannot use 'new' with an expression whose type lacks a call or construct signature."
const watcher = new Watcher(root, {
dot: false,
dot: true,
glob: extensions.map(extension => '**/*.' + extension),
ignored: ignorePattern,
});
Expand Down
5 changes: 3 additions & 2 deletions packages/jest-haste-map/tsconfig.json
Expand Up @@ -5,9 +5,10 @@
"outDir": "build"
},
"references": [
{"path": "../jest-worker"},
{"path": "../jest-regex-util"},
{"path": "../jest-serializer"},
{"path": "../jest-types"},
{"path": "../jest-util"},
{"path": "../jest-types"}
{"path": "../jest-worker"}
]
}
1 change: 1 addition & 0 deletions yarn.lock
Expand Up @@ -11212,6 +11212,7 @@ fsevents@^1.2.7:
fb-watchman: ^2.0.0
fsevents: ^2.1.2
graceful-fs: ^4.2.4
jest-regex-util: ^26.0.0
jest-serializer: ^26.1.0
jest-util: ^26.1.0
jest-worker: ^26.1.0
Expand Down