metro-file-map 0.80.5 → 0.80.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/Watcher.js +0 -20
- package/src/Watcher.js.flow +2 -2
- package/src/cache/DiskCacheManager.js +0 -13
- package/src/constants.js +1 -29
- package/src/crawlers/__fixtures__/directory/bar.js +0 -10
- package/src/crawlers/__fixtures__/foo.js +0 -10
- package/src/crawlers/__fixtures__/ignored/hidden.js +0 -10
- package/src/crawlers/__fixtures__/link-to-directory/bar.js +0 -10
- package/src/crawlers/__fixtures__/link-to-foo.js +0 -10
- package/src/crawlers/node/hasNativeFindSupport.js +0 -12
- package/src/crawlers/node/index.js +9 -24
- package/src/crawlers/node/index.js.flow +6 -3
- package/src/crawlers/watchman/index.js +16 -52
- package/src/crawlers/watchman/index.js.flow +14 -8
- package/src/crawlers/watchman/planQuery.js +0 -64
- package/src/flow-types.d.ts +1 -1
- package/src/flow-types.js +0 -11
- package/src/flow-types.js.flow +29 -1
- package/src/getMockName.js +0 -10
- package/src/index.js +18 -216
- package/src/index.js.flow +16 -11
- package/src/lib/DuplicateError.js +0 -11
- package/src/lib/DuplicateHasteCandidatesError.js +0 -11
- package/src/lib/MockMap.js +4 -15
- package/src/lib/MockMap.js.flow +4 -2
- package/src/lib/MutableHasteMap.js +6 -79
- package/src/lib/MutableHasteMap.js.flow +6 -4
- package/src/lib/RootPathUtils.js +168 -0
- package/src/lib/RootPathUtils.js.flow +211 -0
- package/src/lib/TreeFS.js +96 -159
- package/src/lib/TreeFS.js.flow +118 -43
- package/src/lib/checkWatchmanCapabilities.js +4 -12
- package/src/lib/checkWatchmanCapabilities.js.flow +2 -1
- package/src/lib/dependencyExtractor.js +7 -25
- package/src/lib/fast_path.js +27 -34
- package/src/lib/fast_path.js.flow +31 -9
- package/src/lib/getPlatformExtension.js +0 -11
- package/src/lib/normalizePathSeparatorsToPosix.js +0 -10
- package/src/lib/normalizePathSeparatorsToSystem.js +0 -10
- package/src/lib/rootRelativeCacheKeys.js +3 -58
- package/src/lib/rootRelativeCacheKeys.js.flow +3 -2
- package/src/watchers/FSEventsWatcher.js +1 -41
- package/src/watchers/NodeWatcher.js +1 -104
- package/src/watchers/RecrawlWarning.js +0 -19
- package/src/watchers/WatchmanWatcher.js +3 -55
- package/src/watchers/common.js +1 -49
- package/src/worker.js +18 -45
- package/src/workerExclusionList.js +1 -26
package/package.json
CHANGED
package/src/Watcher.js
CHANGED
|
@@ -62,16 +62,6 @@ function _interopRequireWildcard(obj, nodeInterop) {
|
|
|
62
62
|
function _interopRequireDefault(obj) {
|
|
63
63
|
return obj && obj.__esModule ? obj : { default: obj };
|
|
64
64
|
}
|
|
65
|
-
/**
|
|
66
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
67
|
-
*
|
|
68
|
-
* This source code is licensed under the MIT license found in the
|
|
69
|
-
* LICENSE file in the root directory of this source tree.
|
|
70
|
-
*
|
|
71
|
-
* @format
|
|
72
|
-
*
|
|
73
|
-
*/
|
|
74
|
-
|
|
75
65
|
const debug = require("debug")("Metro:Watcher");
|
|
76
66
|
const MAX_WAIT_TIME = 240000;
|
|
77
67
|
let nextInstanceId = 0;
|
|
@@ -120,7 +110,6 @@ class Watcher extends _events.default {
|
|
|
120
110
|
" " +
|
|
121
111
|
error.toString()
|
|
122
112
|
);
|
|
123
|
-
// $FlowFixMe[prop-missing] Found when updating Promise type definition
|
|
124
113
|
return (0, _node.default)(crawlerOptions).catch((e) => {
|
|
125
114
|
throw new Error(
|
|
126
115
|
"Crawler retry failed:\n" +
|
|
@@ -144,7 +133,6 @@ class Watcher extends _events.default {
|
|
|
144
133
|
};
|
|
145
134
|
debug('Beginning crawl with "%s".', crawler);
|
|
146
135
|
try {
|
|
147
|
-
// $FlowFixMe[incompatible-call] Found when updating Promise type definition
|
|
148
136
|
return crawl(crawlerOptions).catch(retry).then(logEnd);
|
|
149
137
|
} catch (error) {
|
|
150
138
|
return retry(error).then(logEnd);
|
|
@@ -152,8 +140,6 @@ class Watcher extends _events.default {
|
|
|
152
140
|
}
|
|
153
141
|
async watch(onChange) {
|
|
154
142
|
const { extensions, ignorePattern, useWatchman } = this._options;
|
|
155
|
-
|
|
156
|
-
// WatchmanWatcher > FSEventsWatcher > sane.NodeWatcher
|
|
157
143
|
const WatcherImpl = useWatchman
|
|
158
144
|
? _WatchmanWatcher.default
|
|
159
145
|
: _FSEventsWatcher.default.isSupported()
|
|
@@ -176,10 +162,7 @@ class Watcher extends _events.default {
|
|
|
176
162
|
const watcherOptions = {
|
|
177
163
|
dot: true,
|
|
178
164
|
glob: [
|
|
179
|
-
// Ensure we always include package.json files, which are crucial for
|
|
180
|
-
/// module resolution.
|
|
181
165
|
"**/package.json",
|
|
182
|
-
// Ensure we always watch any health check files
|
|
183
166
|
"**/" + this._options.healthCheckFilePrefix + "*",
|
|
184
167
|
...extensions.map((extension) => "**/*." + extension),
|
|
185
168
|
],
|
|
@@ -287,9 +270,6 @@ class Watcher extends _events.default {
|
|
|
287
270
|
creationPromise.then(() => observationPromise),
|
|
288
271
|
]);
|
|
289
272
|
this._pendingHealthChecks.delete(basename);
|
|
290
|
-
// Chain a deletion to the creation promise (which may not have even settled yet!),
|
|
291
|
-
// don't await it, and swallow errors. This is just best-effort cleanup.
|
|
292
|
-
// $FlowFixMe[unused-promise]
|
|
293
273
|
creationPromise.then(() =>
|
|
294
274
|
fs.promises.unlink(healthCheckPath).catch(() => {})
|
|
295
275
|
);
|
package/src/Watcher.js.flow
CHANGED
|
@@ -176,8 +176,8 @@ export class Watcher extends EventEmitter {
|
|
|
176
176
|
const WatcherImpl = useWatchman
|
|
177
177
|
? WatchmanWatcher
|
|
178
178
|
: FSEventsWatcher.isSupported()
|
|
179
|
-
|
|
180
|
-
|
|
179
|
+
? FSEventsWatcher
|
|
180
|
+
: NodeWatcher;
|
|
181
181
|
|
|
182
182
|
let watcher = 'node';
|
|
183
183
|
if (WatcherImpl === WatchmanWatcher) {
|
|
@@ -14,17 +14,6 @@ var _v = require("v8");
|
|
|
14
14
|
function _interopRequireDefault(obj) {
|
|
15
15
|
return obj && obj.__esModule ? obj : { default: obj };
|
|
16
16
|
}
|
|
17
|
-
/**
|
|
18
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
19
|
-
*
|
|
20
|
-
* This source code is licensed under the MIT license found in the
|
|
21
|
-
* LICENSE file in the root directory of this source tree.
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* @format
|
|
25
|
-
* @oncall react_native
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
17
|
const DEFAULT_PREFIX = "metro-file-map";
|
|
29
18
|
const DEFAULT_DIRECTORY = (0, _os.tmpdir)();
|
|
30
19
|
class DiskCacheManager {
|
|
@@ -55,10 +44,8 @@ class DiskCacheManager {
|
|
|
55
44
|
);
|
|
56
45
|
} catch (e) {
|
|
57
46
|
if (e?.code === "ENOENT") {
|
|
58
|
-
// Cache file not found - not considered an error.
|
|
59
47
|
return null;
|
|
60
48
|
}
|
|
61
|
-
// Rethrow anything else.
|
|
62
49
|
throw e;
|
|
63
50
|
}
|
|
64
51
|
}
|
package/src/constants.js
CHANGED
|
@@ -1,32 +1,7 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the MIT license found in the
|
|
5
|
-
* LICENSE file in the root directory of this source tree.
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* @noformat - Flow comment syntax
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
/*
|
|
12
|
-
* This file exports a set of constants that are used for Jest's haste map
|
|
13
|
-
* serialization. On very large repositories, the haste map cache becomes very
|
|
14
|
-
* large to the point where it is the largest overhead in starting up Jest.
|
|
15
|
-
*
|
|
16
|
-
* This constant key map allows to keep the map smaller without having to build
|
|
17
|
-
* a custom serialization library.
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
/*::
|
|
21
|
-
import type {HType} from './flow-types';
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
1
|
"use strict";
|
|
25
2
|
|
|
26
|
-
const constants
|
|
27
|
-
/* dependency serialization */
|
|
3
|
+
const constants = {
|
|
28
4
|
DEPENDENCY_DELIM: "\0",
|
|
29
|
-
/* file map attributes */
|
|
30
5
|
ID: 0,
|
|
31
6
|
MTIME: 1,
|
|
32
7
|
SIZE: 2,
|
|
@@ -34,13 +9,10 @@ const constants /*: HType */ = {
|
|
|
34
9
|
DEPENDENCIES: 4,
|
|
35
10
|
SHA1: 5,
|
|
36
11
|
SYMLINK: 6,
|
|
37
|
-
/* module map attributes */
|
|
38
12
|
PATH: 0,
|
|
39
13
|
TYPE: 1,
|
|
40
|
-
/* module types */
|
|
41
14
|
MODULE: 0,
|
|
42
15
|
PACKAGE: 1,
|
|
43
|
-
/* platforms */
|
|
44
16
|
GENERIC_PLATFORM: "g",
|
|
45
17
|
NATIVE_PLATFORM: "native",
|
|
46
18
|
};
|
|
@@ -5,21 +5,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = hasNativeFindSupport;
|
|
7
7
|
var _child_process = require("child_process");
|
|
8
|
-
/**
|
|
9
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
10
|
-
*
|
|
11
|
-
* This source code is licensed under the MIT license found in the
|
|
12
|
-
* LICENSE file in the root directory of this source tree.
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* @format
|
|
16
|
-
* @oncall react_native
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
8
|
async function hasNativeFindSupport() {
|
|
20
9
|
try {
|
|
21
10
|
return await new Promise((resolve) => {
|
|
22
|
-
// Check the find binary supports the non-POSIX -iname parameter wrapped in parens.
|
|
23
11
|
const args = [
|
|
24
12
|
".",
|
|
25
13
|
"-type",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _RootPathUtils = require("../../lib/RootPathUtils");
|
|
4
4
|
var _hasNativeFindSupport = _interopRequireDefault(
|
|
5
5
|
require("./hasNativeFindSupport")
|
|
6
6
|
);
|
|
@@ -8,9 +8,6 @@ var _child_process = require("child_process");
|
|
|
8
8
|
var fs = _interopRequireWildcard(require("graceful-fs"));
|
|
9
9
|
var _os = require("os");
|
|
10
10
|
var path = _interopRequireWildcard(require("path"));
|
|
11
|
-
function _interopRequireDefault(obj) {
|
|
12
|
-
return obj && obj.__esModule ? obj : { default: obj };
|
|
13
|
-
}
|
|
14
11
|
function _getRequireWildcardCache(nodeInterop) {
|
|
15
12
|
if (typeof WeakMap !== "function") return null;
|
|
16
13
|
var cacheBabelInterop = new WeakMap();
|
|
@@ -51,21 +48,14 @@ function _interopRequireWildcard(obj, nodeInterop) {
|
|
|
51
48
|
}
|
|
52
49
|
return newObj;
|
|
53
50
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
* This source code is licensed under the MIT license found in the
|
|
58
|
-
* LICENSE file in the root directory of this source tree.
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
* @format
|
|
62
|
-
* @oncall react_native
|
|
63
|
-
*/
|
|
64
|
-
|
|
51
|
+
function _interopRequireDefault(obj) {
|
|
52
|
+
return obj && obj.__esModule ? obj : { default: obj };
|
|
53
|
+
}
|
|
65
54
|
const debug = require("debug")("Metro:NodeCrawler");
|
|
66
55
|
function find(roots, extensions, ignore, includeSymlinks, rootDir, callback) {
|
|
67
56
|
const result = new Map();
|
|
68
57
|
let activeCalls = 0;
|
|
58
|
+
const pathUtils = new _RootPathUtils.RootPathUtils(rootDir);
|
|
69
59
|
function search(directory) {
|
|
70
60
|
activeCalls++;
|
|
71
61
|
fs.readdir(
|
|
@@ -97,7 +87,7 @@ function find(roots, extensions, ignore, includeSymlinks, rootDir, callback) {
|
|
|
97
87
|
if (!err && stat) {
|
|
98
88
|
const ext = path.extname(file).substr(1);
|
|
99
89
|
if (stat.isSymbolicLink() || extensions.includes(ext)) {
|
|
100
|
-
result.set(
|
|
90
|
+
result.set(pathUtils.absoluteToNormal(file), [
|
|
101
91
|
"",
|
|
102
92
|
stat.mtime.getTime(),
|
|
103
93
|
stat.size,
|
|
@@ -133,17 +123,13 @@ function findNative(
|
|
|
133
123
|
rootDir,
|
|
134
124
|
callback
|
|
135
125
|
) {
|
|
136
|
-
// Examples:
|
|
137
|
-
// ( ( -type f ( -iname *.js ) ) )
|
|
138
|
-
// ( ( -type f ( -iname *.js -o -iname *.ts ) ) )
|
|
139
|
-
// ( ( -type f ( -iname *.js ) ) -o -type l )
|
|
140
|
-
// ( ( -type f ) -o -type l )
|
|
141
126
|
const extensionClause = extensions.length
|
|
142
127
|
? `( ${extensions.map((ext) => `-iname *.${ext}`).join(" -o ")} )`
|
|
143
|
-
: "";
|
|
128
|
+
: "";
|
|
144
129
|
const expression = `( ( -type f ${extensionClause} ) ${
|
|
145
130
|
includeSymlinks ? "-o -type l " : ""
|
|
146
131
|
})`;
|
|
132
|
+
const pathUtils = new _RootPathUtils.RootPathUtils(rootDir);
|
|
147
133
|
const child = (0, _child_process.spawn)(
|
|
148
134
|
"find",
|
|
149
135
|
roots.concat(expression.split(" "))
|
|
@@ -169,7 +155,7 @@ function findNative(
|
|
|
169
155
|
lines.forEach((path) => {
|
|
170
156
|
fs.lstat(path, (err, stat) => {
|
|
171
157
|
if (!err && stat) {
|
|
172
|
-
result.set(
|
|
158
|
+
result.set(pathUtils.absoluteToNormal(path), [
|
|
173
159
|
"",
|
|
174
160
|
stat.mtime.getTime(),
|
|
175
161
|
stat.size,
|
|
@@ -211,7 +197,6 @@ module.exports = async function nodeCrawl(options) {
|
|
|
211
197
|
const difference = previousState.fileSystem.getDifference(fileData);
|
|
212
198
|
perfLogger?.point("nodeCrawl_end");
|
|
213
199
|
try {
|
|
214
|
-
// TODO: Use AbortSignal.reason directly when Flow supports it
|
|
215
200
|
abortSignal?.throwIfAborted();
|
|
216
201
|
} catch (e) {
|
|
217
202
|
reject(e);
|
|
@@ -16,7 +16,7 @@ import type {
|
|
|
16
16
|
IgnoreMatcher,
|
|
17
17
|
} from '../../flow-types';
|
|
18
18
|
|
|
19
|
-
import
|
|
19
|
+
import {RootPathUtils} from '../../lib/RootPathUtils';
|
|
20
20
|
import hasNativeFindSupport from './hasNativeFindSupport';
|
|
21
21
|
import {spawn} from 'child_process';
|
|
22
22
|
import * as fs from 'graceful-fs';
|
|
@@ -37,6 +37,7 @@ function find(
|
|
|
37
37
|
): void {
|
|
38
38
|
const result: FileData = new Map();
|
|
39
39
|
let activeCalls = 0;
|
|
40
|
+
const pathUtils = new RootPathUtils(rootDir);
|
|
40
41
|
|
|
41
42
|
function search(directory: string): void {
|
|
42
43
|
activeCalls++;
|
|
@@ -71,7 +72,7 @@ function find(
|
|
|
71
72
|
if (!err && stat) {
|
|
72
73
|
const ext = path.extname(file).substr(1);
|
|
73
74
|
if (stat.isSymbolicLink() || extensions.includes(ext)) {
|
|
74
|
-
result.set(
|
|
75
|
+
result.set(pathUtils.absoluteToNormal(file), [
|
|
75
76
|
'',
|
|
76
77
|
stat.mtime.getTime(),
|
|
77
78
|
stat.size,
|
|
@@ -122,6 +123,8 @@ function findNative(
|
|
|
122
123
|
includeSymlinks ? '-o -type l ' : ''
|
|
123
124
|
})`;
|
|
124
125
|
|
|
126
|
+
const pathUtils = new RootPathUtils(rootDir);
|
|
127
|
+
|
|
125
128
|
const child = spawn('find', roots.concat(expression.split(' ')));
|
|
126
129
|
let stdout = '';
|
|
127
130
|
if (child.stdout == null) {
|
|
@@ -145,7 +148,7 @@ function findNative(
|
|
|
145
148
|
lines.forEach(path => {
|
|
146
149
|
fs.lstat(path, (err, stat) => {
|
|
147
150
|
if (!err && stat) {
|
|
148
|
-
result.set(
|
|
151
|
+
result.set(pathUtils.absoluteToNormal(path), [
|
|
149
152
|
'',
|
|
150
153
|
stat.mtime.getTime(),
|
|
151
154
|
stat.size,
|
|
@@ -1,19 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
var fastPath = _interopRequireWildcard(require("../../lib/fast_path"));
|
|
4
3
|
var _normalizePathSeparatorsToPosix = _interopRequireDefault(
|
|
5
4
|
require("../../lib/normalizePathSeparatorsToPosix")
|
|
6
5
|
);
|
|
7
6
|
var _normalizePathSeparatorsToSystem = _interopRequireDefault(
|
|
8
7
|
require("../../lib/normalizePathSeparatorsToSystem")
|
|
9
8
|
);
|
|
9
|
+
var _RootPathUtils = require("../../lib/RootPathUtils");
|
|
10
10
|
var _planQuery = require("./planQuery");
|
|
11
11
|
var _invariant = _interopRequireDefault(require("invariant"));
|
|
12
12
|
var path = _interopRequireWildcard(require("path"));
|
|
13
13
|
var _perf_hooks = require("perf_hooks");
|
|
14
|
-
function _interopRequireDefault(obj) {
|
|
15
|
-
return obj && obj.__esModule ? obj : { default: obj };
|
|
16
|
-
}
|
|
17
14
|
function _getRequireWildcardCache(nodeInterop) {
|
|
18
15
|
if (typeof WeakMap !== "function") return null;
|
|
19
16
|
var cacheBabelInterop = new WeakMap();
|
|
@@ -54,17 +51,9 @@ function _interopRequireWildcard(obj, nodeInterop) {
|
|
|
54
51
|
}
|
|
55
52
|
return newObj;
|
|
56
53
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
* This source code is licensed under the MIT license found in the
|
|
61
|
-
* LICENSE file in the root directory of this source tree.
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
* @format
|
|
65
|
-
* @oncall react_native
|
|
66
|
-
*/
|
|
67
|
-
|
|
54
|
+
function _interopRequireDefault(obj) {
|
|
55
|
+
return obj && obj.__esModule ? obj : { default: obj };
|
|
56
|
+
}
|
|
68
57
|
const watchman = require("fb-watchman");
|
|
69
58
|
const WATCHMAN_WARNING_INITIAL_DELAY_MILLISECONDS = 10000;
|
|
70
59
|
const WATCHMAN_WARNING_INTERVAL_MILLISECONDS = 20000;
|
|
@@ -89,6 +78,7 @@ module.exports = async function watchmanCrawl({
|
|
|
89
78
|
}) {
|
|
90
79
|
abortSignal?.throwIfAborted();
|
|
91
80
|
const client = new watchman.Client();
|
|
81
|
+
const pathUtils = new _RootPathUtils.RootPathUtils(rootDir);
|
|
92
82
|
abortSignal?.addEventListener("abort", () => client.end());
|
|
93
83
|
perfLogger?.point("watchmanCrawl_start");
|
|
94
84
|
const newClocks = new Map();
|
|
@@ -96,11 +86,7 @@ module.exports = async function watchmanCrawl({
|
|
|
96
86
|
client.on("error", (error) => {
|
|
97
87
|
clientError = makeWatchmanError(error);
|
|
98
88
|
});
|
|
99
|
-
const cmd = async (
|
|
100
|
-
command,
|
|
101
|
-
// $FlowFixMe[unclear-type] - Fix to use fb-watchman types
|
|
102
|
-
...args
|
|
103
|
-
) => {
|
|
89
|
+
const cmd = async (command, ...args) => {
|
|
104
90
|
let didLogWatchmanWaitMessage = false;
|
|
105
91
|
const startTime = _perf_hooks.performance.now();
|
|
106
92
|
const logWatchmanWaitMessage = () => {
|
|
@@ -120,7 +106,6 @@ module.exports = async function watchmanCrawl({
|
|
|
120
106
|
}, WATCHMAN_WARNING_INITIAL_DELAY_MILLISECONDS);
|
|
121
107
|
try {
|
|
122
108
|
const response = await new Promise((resolve, reject) =>
|
|
123
|
-
// $FlowFixMe[incompatible-call] - dynamic call of command
|
|
124
109
|
client.command([command, ...args], (error, result) =>
|
|
125
110
|
error ? reject(makeWatchmanError(error)) : resolve(result)
|
|
126
111
|
)
|
|
@@ -132,10 +117,8 @@ module.exports = async function watchmanCrawl({
|
|
|
132
117
|
command,
|
|
133
118
|
});
|
|
134
119
|
}
|
|
135
|
-
// $FlowFixMe[incompatible-return]
|
|
136
120
|
return response;
|
|
137
121
|
} finally {
|
|
138
|
-
// $FlowFixMe[incompatible-call] clearInterval / clearTimeout are interchangeable
|
|
139
122
|
clearInterval(intervalOrTimeoutId);
|
|
140
123
|
if (didLogWatchmanWaitMessage) {
|
|
141
124
|
onStatus({
|
|
@@ -155,8 +138,6 @@ module.exports = async function watchmanCrawl({
|
|
|
155
138
|
const response = await cmd("watch-project", root);
|
|
156
139
|
perfLogger?.point(`watchmanCrawl/watchProject_${index}_end`);
|
|
157
140
|
const existing = watchmanRoots.get(response.watch);
|
|
158
|
-
// A root can only be filtered if it was never seen with a
|
|
159
|
-
// relative_path before.
|
|
160
141
|
const canBeFiltered = !existing || existing.directoryFilters.length > 0;
|
|
161
142
|
if (canBeFiltered) {
|
|
162
143
|
if (response.relative_path) {
|
|
@@ -167,9 +148,6 @@ module.exports = async function watchmanCrawl({
|
|
|
167
148
|
),
|
|
168
149
|
});
|
|
169
150
|
} else {
|
|
170
|
-
// Make the filter directories an empty array to signal that this
|
|
171
|
-
// root was already seen and needs to be watched for all files or
|
|
172
|
-
// directories.
|
|
173
151
|
watchmanRoots.set(response.watch, {
|
|
174
152
|
watcher: response.watcher,
|
|
175
153
|
directoryFilters: [],
|
|
@@ -187,18 +165,14 @@ module.exports = async function watchmanCrawl({
|
|
|
187
165
|
let isFresh = false;
|
|
188
166
|
await Promise.all(
|
|
189
167
|
Array.from(rootProjectDirMappings).map(
|
|
190
|
-
async ([
|
|
191
|
-
// Jest is only going to store one type of clock; a string that
|
|
192
|
-
// represents a local clock. However, the Watchman crawler supports
|
|
193
|
-
// a second type of clock that can be written by automation outside of
|
|
194
|
-
// Jest, called an "scm query", which fetches changed files based on
|
|
195
|
-
// source control mergebases. The reason this is necessary is because
|
|
196
|
-
// local clocks are not portable across systems, but scm queries are.
|
|
197
|
-
// By using scm queries, we can create the haste map on a different
|
|
198
|
-
// system and import it, transforming the clock into a local clock.
|
|
168
|
+
async ([posixSeparatedRoot, { directoryFilters, watcher }], index) => {
|
|
199
169
|
const since = previousState.clocks.get(
|
|
200
170
|
(0, _normalizePathSeparatorsToPosix.default)(
|
|
201
|
-
|
|
171
|
+
pathUtils.absoluteToNormal(
|
|
172
|
+
(0, _normalizePathSeparatorsToSystem.default)(
|
|
173
|
+
posixSeparatedRoot
|
|
174
|
+
)
|
|
175
|
+
)
|
|
202
176
|
)
|
|
203
177
|
);
|
|
204
178
|
perfLogger?.annotate({
|
|
@@ -220,18 +194,14 @@ module.exports = async function watchmanCrawl({
|
|
|
220
194
|
},
|
|
221
195
|
});
|
|
222
196
|
perfLogger?.point(`watchmanCrawl/query_${index}_start`);
|
|
223
|
-
const response = await cmd("query",
|
|
197
|
+
const response = await cmd("query", posixSeparatedRoot, query);
|
|
224
198
|
perfLogger?.point(`watchmanCrawl/query_${index}_end`);
|
|
225
|
-
|
|
226
|
-
// When a source-control query is used, we ignore the "is fresh"
|
|
227
|
-
// response from Watchman because it will be true despite the query
|
|
228
|
-
// being incremental.
|
|
229
199
|
const isSourceControlQuery =
|
|
230
200
|
typeof since !== "string" && since?.scm?.["mergebase-with"] != null;
|
|
231
201
|
if (!isSourceControlQuery) {
|
|
232
202
|
isFresh = isFresh || response.is_fresh_instance;
|
|
233
203
|
}
|
|
234
|
-
results.set(
|
|
204
|
+
results.set(posixSeparatedRoot, response);
|
|
235
205
|
}
|
|
236
206
|
)
|
|
237
207
|
);
|
|
@@ -282,10 +252,9 @@ module.exports = async function watchmanCrawl({
|
|
|
282
252
|
const freshFileData = new Map();
|
|
283
253
|
for (const [watchRoot, response] of results) {
|
|
284
254
|
const fsRoot = (0, _normalizePathSeparatorsToSystem.default)(watchRoot);
|
|
285
|
-
const relativeFsRoot =
|
|
255
|
+
const relativeFsRoot = pathUtils.absoluteToNormal(fsRoot);
|
|
286
256
|
newClocks.set(
|
|
287
257
|
(0, _normalizePathSeparatorsToPosix.default)(relativeFsRoot),
|
|
288
|
-
// Ensure we persist only the local clock.
|
|
289
258
|
typeof response.clock === "string" ? response.clock : response.clock.clock
|
|
290
259
|
);
|
|
291
260
|
for (const fileData of response.files) {
|
|
@@ -293,13 +262,11 @@ module.exports = async function watchmanCrawl({
|
|
|
293
262
|
fsRoot +
|
|
294
263
|
path.sep +
|
|
295
264
|
(0, _normalizePathSeparatorsToSystem.default)(fileData.name);
|
|
296
|
-
const relativeFilePath =
|
|
265
|
+
const relativeFilePath = pathUtils.absoluteToNormal(filePath);
|
|
297
266
|
if (!fileData.exists) {
|
|
298
267
|
if (!isFresh) {
|
|
299
268
|
removedFiles.add(relativeFilePath);
|
|
300
269
|
}
|
|
301
|
-
// Whether watchman can return exists: false in a fresh instance
|
|
302
|
-
// response is unknown, but there's nothing we need to do in that case.
|
|
303
270
|
} else if (!ignore(filePath)) {
|
|
304
271
|
const { mtime_ms, size } = fileData;
|
|
305
272
|
(0, _invariant.default)(
|
|
@@ -317,9 +284,6 @@ module.exports = async function watchmanCrawl({
|
|
|
317
284
|
symlinkInfo = fileData["symlink_target"] ?? 1;
|
|
318
285
|
}
|
|
319
286
|
const nextData = ["", mtime, size, 0, "", sha1hex ?? null, symlinkInfo];
|
|
320
|
-
|
|
321
|
-
// If watchman is fresh, the removed files map starts with all files
|
|
322
|
-
// and we remove them as we verify they still exist.
|
|
323
287
|
if (isFresh) {
|
|
324
288
|
freshFileData.set(relativeFilePath, nextData);
|
|
325
289
|
} else {
|
|
@@ -20,9 +20,9 @@ import type {
|
|
|
20
20
|
} from '../../flow-types';
|
|
21
21
|
import type {WatchmanQueryResponse, WatchmanWatchResponse} from 'fb-watchman';
|
|
22
22
|
|
|
23
|
-
import * as fastPath from '../../lib/fast_path';
|
|
24
23
|
import normalizePathSeparatorsToPosix from '../../lib/normalizePathSeparatorsToPosix';
|
|
25
24
|
import normalizePathSeparatorsToSystem from '../../lib/normalizePathSeparatorsToSystem';
|
|
25
|
+
import {RootPathUtils} from '../../lib/RootPathUtils';
|
|
26
26
|
import {planQuery} from './planQuery';
|
|
27
27
|
import invariant from 'invariant';
|
|
28
28
|
import * as path from 'path';
|
|
@@ -31,7 +31,7 @@ import {performance} from 'perf_hooks';
|
|
|
31
31
|
const watchman = require('fb-watchman');
|
|
32
32
|
|
|
33
33
|
type WatchmanRoots = Map<
|
|
34
|
-
string,
|
|
34
|
+
string, // Posix-separated absolute path
|
|
35
35
|
$ReadOnly<{directoryFilters: Array<string>, watcher: string}>,
|
|
36
36
|
>;
|
|
37
37
|
|
|
@@ -66,6 +66,7 @@ module.exports = async function watchmanCrawl({
|
|
|
66
66
|
abortSignal?.throwIfAborted();
|
|
67
67
|
|
|
68
68
|
const client = new watchman.Client();
|
|
69
|
+
const pathUtils = new RootPathUtils(rootDir);
|
|
69
70
|
abortSignal?.addEventListener('abort', () => client.end());
|
|
70
71
|
|
|
71
72
|
perfLogger?.point('watchmanCrawl_start');
|
|
@@ -177,9 +178,10 @@ module.exports = async function watchmanCrawl({
|
|
|
177
178
|
perfLogger?.point('watchmanCrawl/queryWatchmanForDirs_start');
|
|
178
179
|
const results = new Map<string, WatchmanQueryResponse>();
|
|
179
180
|
let isFresh = false;
|
|
181
|
+
|
|
180
182
|
await Promise.all(
|
|
181
183
|
Array.from(rootProjectDirMappings).map(
|
|
182
|
-
async ([
|
|
184
|
+
async ([posixSeparatedRoot, {directoryFilters, watcher}], index) => {
|
|
183
185
|
// Jest is only going to store one type of clock; a string that
|
|
184
186
|
// represents a local clock. However, the Watchman crawler supports
|
|
185
187
|
// a second type of clock that can be written by automation outside of
|
|
@@ -189,7 +191,11 @@ module.exports = async function watchmanCrawl({
|
|
|
189
191
|
// By using scm queries, we can create the haste map on a different
|
|
190
192
|
// system and import it, transforming the clock into a local clock.
|
|
191
193
|
const since = previousState.clocks.get(
|
|
192
|
-
normalizePathSeparatorsToPosix(
|
|
194
|
+
normalizePathSeparatorsToPosix(
|
|
195
|
+
pathUtils.absoluteToNormal(
|
|
196
|
+
normalizePathSeparatorsToSystem(posixSeparatedRoot),
|
|
197
|
+
),
|
|
198
|
+
),
|
|
193
199
|
);
|
|
194
200
|
|
|
195
201
|
perfLogger?.annotate({
|
|
@@ -216,7 +222,7 @@ module.exports = async function watchmanCrawl({
|
|
|
216
222
|
perfLogger?.point(`watchmanCrawl/query_${index}_start`);
|
|
217
223
|
const response = await cmd<WatchmanQueryResponse>(
|
|
218
224
|
'query',
|
|
219
|
-
|
|
225
|
+
posixSeparatedRoot,
|
|
220
226
|
query,
|
|
221
227
|
);
|
|
222
228
|
perfLogger?.point(`watchmanCrawl/query_${index}_end`);
|
|
@@ -230,7 +236,7 @@ module.exports = async function watchmanCrawl({
|
|
|
230
236
|
isFresh = isFresh || response.is_fresh_instance;
|
|
231
237
|
}
|
|
232
238
|
|
|
233
|
-
results.set(
|
|
239
|
+
results.set(posixSeparatedRoot, response);
|
|
234
240
|
},
|
|
235
241
|
),
|
|
236
242
|
);
|
|
@@ -288,7 +294,7 @@ module.exports = async function watchmanCrawl({
|
|
|
288
294
|
|
|
289
295
|
for (const [watchRoot, response] of results) {
|
|
290
296
|
const fsRoot = normalizePathSeparatorsToSystem(watchRoot);
|
|
291
|
-
const relativeFsRoot =
|
|
297
|
+
const relativeFsRoot = pathUtils.absoluteToNormal(fsRoot);
|
|
292
298
|
newClocks.set(
|
|
293
299
|
normalizePathSeparatorsToPosix(relativeFsRoot),
|
|
294
300
|
// Ensure we persist only the local clock.
|
|
@@ -300,7 +306,7 @@ module.exports = async function watchmanCrawl({
|
|
|
300
306
|
for (const fileData of response.files) {
|
|
301
307
|
const filePath =
|
|
302
308
|
fsRoot + path.sep + normalizePathSeparatorsToSystem(fileData.name);
|
|
303
|
-
const relativeFilePath =
|
|
309
|
+
const relativeFilePath = pathUtils.absoluteToNormal(filePath);
|
|
304
310
|
|
|
305
311
|
if (!fileData.exists) {
|
|
306
312
|
if (!isFresh) {
|