Created
August 4, 2017 14:11
-
-
Save JCMais/09c60b41f421658456e1d6ad38b52998 to your computer and use it in GitHub Desktop.
Fixing https://github.com/facebook/watchman/issues/479, edit jest-haste-map/build/crawlers/watchman.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; /** | |
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* LICENSE file in the root directory of this source tree. An additional grant | |
* of patent rights can be found in the PATENTS file in the same directory. | |
* | |
* | |
*/ | |
const path = require('path'); | |
const watchman = require('fb-watchman'); | |
const H = require('../constants'); | |
const watchmanURL = | |
'https://facebook.github.io/watchman/docs/troubleshooting.html'; | |
function isDescendant(root, child) { | |
return child.startsWith(root); | |
} | |
function WatchmanError(error) { | |
return new Error( | |
`Watchman error: ${error.message.trim()}. Make sure watchman ` + | |
`is running for this project. See ${watchmanURL}.`); | |
} | |
module.exports = function watchmanCrawl( | |
options) | |
{const | |
data = options.data,extensions = options.extensions,ignore = options.ignore,roots = options.roots; | |
return new Promise((resolve, reject) => { | |
const client = new watchman.Client(); | |
client.on('error', error => reject(error)); | |
const cmd = args => | |
new Promise((resolve, reject) => { | |
client.command(args, (error, result) => { | |
if (error) { | |
reject(error); | |
} else { | |
resolve(result); | |
} | |
}); | |
}); | |
const clocks = data.clocks; | |
let files = data.files; | |
return Promise.all(roots.map(root => cmd(['watch-project', root]))). | |
then(responses => { | |
const watchmanRoots = Array.from( | |
new Set(responses.map(response => response.watch))); | |
return Promise.all( | |
watchmanRoots.map(root => { | |
root = root.replace(/\//g, '\\'); | |
// Build an expression to filter the output by the relevant roots. | |
const dirExpr = ['anyof']; | |
roots.forEach(subRoot => { | |
subRoot = subRoot.replace(/\//g, '\\'); | |
if (isDescendant(root, subRoot)) { | |
dirExpr.push(['dirname', path.relative(root, subRoot)]); | |
} | |
}); | |
const expression = [ | |
'allof', | |
['type', 'f'], | |
['anyof'].concat( | |
extensions.map(extension => ['suffix', extension]))]; | |
if (dirExpr.length > 1) { | |
expression.push(dirExpr); | |
} | |
const fields = ['name', 'exists', 'mtime_ms']; | |
const query = clocks[root] ? | |
// Use the `since` generator if we have a clock available | |
{ expression, fields, since: clocks[root] } : | |
// Otherwise use the `suffix` generator | |
{ expression, fields, suffix: extensions }; | |
return cmd(['query', root, query]).then(response => ({ | |
response, | |
root })); | |
})). | |
then(pairs => { | |
// Reset the file map if watchman was restarted and sends us a list of | |
// files. | |
if (pairs.some(pair => pair.response.is_fresh_instance)) { | |
files = Object.create(null); | |
} | |
pairs.forEach(pair => { | |
const root = pair.root; | |
const response = pair.response; | |
if ('warning' in response) { | |
console.warn('watchman warning: ', response.warning); | |
} | |
clocks[root] = response.clock; | |
response.files.forEach(fileData => { | |
const name = (root + path.sep + fileData.name).replace(/\//g, '\\'); | |
if (!fileData.exists) { | |
delete files[name]; | |
} else if (!ignore(name)) { | |
const mtime = typeof fileData.mtime_ms === 'number' ? | |
fileData.mtime_ms : | |
fileData.mtime_ms.toNumber(); | |
const isNew = | |
!data.files[name] || data.files[name][H.MTIME] !== mtime; | |
if (isNew) { | |
// See ../constants.js | |
files[name] = ['', mtime, 0, []]; | |
} else { | |
files[name] = data.files[name]; | |
} | |
} | |
}); | |
}); | |
}); | |
}). | |
then(() => { | |
client.end(); | |
data.files = files; | |
resolve(data); | |
}). | |
catch(error => { | |
client.end(); | |
reject(WatchmanError(error)); | |
}); | |
}); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment