node.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. 'use strict';
  2. function _fs() {
  3. const data = _interopRequireDefault(require('fs'));
  4. _fs = function _fs() {
  5. return data;
  6. };
  7. return data;
  8. }
  9. function _path() {
  10. const data = _interopRequireDefault(require('path'));
  11. _path = function _path() {
  12. return data;
  13. };
  14. return data;
  15. }
  16. function _child_process() {
  17. const data = require('child_process');
  18. _child_process = function _child_process() {
  19. return data;
  20. };
  21. return data;
  22. }
  23. var _constants = _interopRequireDefault(require('../constants'));
  24. var fastPath = _interopRequireWildcard(require('../lib/fast_path'));
  25. function _interopRequireWildcard(obj) {
  26. if (obj && obj.__esModule) {
  27. return obj;
  28. } else {
  29. var newObj = {};
  30. if (obj != null) {
  31. for (var key in obj) {
  32. if (Object.prototype.hasOwnProperty.call(obj, key)) {
  33. var desc =
  34. Object.defineProperty && Object.getOwnPropertyDescriptor
  35. ? Object.getOwnPropertyDescriptor(obj, key)
  36. : {};
  37. if (desc.get || desc.set) {
  38. Object.defineProperty(newObj, key, desc);
  39. } else {
  40. newObj[key] = obj[key];
  41. }
  42. }
  43. }
  44. }
  45. newObj.default = obj;
  46. return newObj;
  47. }
  48. }
  49. function _interopRequireDefault(obj) {
  50. return obj && obj.__esModule ? obj : {default: obj};
  51. }
  52. function _slicedToArray(arr, i) {
  53. return (
  54. _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest()
  55. );
  56. }
  57. function _nonIterableRest() {
  58. throw new TypeError('Invalid attempt to destructure non-iterable instance');
  59. }
  60. function _iterableToArrayLimit(arr, i) {
  61. var _arr = [];
  62. var _n = true;
  63. var _d = false;
  64. var _e = undefined;
  65. try {
  66. for (
  67. var _i = arr[Symbol.iterator](), _s;
  68. !(_n = (_s = _i.next()).done);
  69. _n = true
  70. ) {
  71. _arr.push(_s.value);
  72. if (i && _arr.length === i) break;
  73. }
  74. } catch (err) {
  75. _d = true;
  76. _e = err;
  77. } finally {
  78. try {
  79. if (!_n && _i['return'] != null) _i['return']();
  80. } finally {
  81. if (_d) throw _e;
  82. }
  83. }
  84. return _arr;
  85. }
  86. function _arrayWithHoles(arr) {
  87. if (Array.isArray(arr)) return arr;
  88. }
  89. function find(roots, extensions, ignore, callback) {
  90. const result = [];
  91. let activeCalls = 0;
  92. function search(directory) {
  93. activeCalls++;
  94. _fs().default.readdir(directory, (err, names) => {
  95. activeCalls--;
  96. if (err) {
  97. callback(result);
  98. return;
  99. }
  100. names.forEach(file => {
  101. file = _path().default.join(directory, file);
  102. if (ignore(file)) {
  103. return;
  104. }
  105. activeCalls++;
  106. _fs().default.lstat(file, (err, stat) => {
  107. activeCalls--;
  108. if (!err && stat && !stat.isSymbolicLink()) {
  109. if (stat.isDirectory()) {
  110. search(file);
  111. } else {
  112. const ext = _path()
  113. .default.extname(file)
  114. .substr(1);
  115. if (extensions.indexOf(ext) !== -1) {
  116. result.push([file, stat.mtime.getTime(), stat.size]);
  117. }
  118. }
  119. }
  120. if (activeCalls === 0) {
  121. callback(result);
  122. }
  123. });
  124. });
  125. if (activeCalls === 0) {
  126. callback(result);
  127. }
  128. });
  129. }
  130. if (roots.length > 0) {
  131. roots.forEach(search);
  132. } else {
  133. callback(result);
  134. }
  135. }
  136. function findNative(roots, extensions, ignore, callback) {
  137. const args = Array.from(roots);
  138. args.push('-type', 'f');
  139. if (extensions.length) {
  140. args.push('(');
  141. }
  142. extensions.forEach((ext, index) => {
  143. if (index) {
  144. args.push('-o');
  145. }
  146. args.push('-iname');
  147. args.push('*.' + ext);
  148. });
  149. if (extensions.length) {
  150. args.push(')');
  151. }
  152. const child = (0, _child_process().spawn)('find', args);
  153. let stdout = '';
  154. if (child.stdout === null) {
  155. throw new Error(
  156. 'stdout is null - this should never happen. Please open up an issue at https://github.com/facebook/jest'
  157. );
  158. }
  159. child.stdout.setEncoding('utf-8');
  160. child.stdout.on('data', data => (stdout += data));
  161. child.stdout.on('close', () => {
  162. const lines = stdout
  163. .trim()
  164. .split('\n')
  165. .filter(x => !ignore(x));
  166. const result = [];
  167. let count = lines.length;
  168. if (!count) {
  169. callback([]);
  170. } else {
  171. lines.forEach(path => {
  172. _fs().default.stat(path, (err, stat) => {
  173. if (!err && stat) {
  174. result.push([path, stat.mtime.getTime(), stat.size]);
  175. }
  176. if (--count === 0) {
  177. callback(result);
  178. }
  179. });
  180. });
  181. }
  182. });
  183. }
  184. module.exports = function nodeCrawl(options) {
  185. const data = options.data,
  186. extensions = options.extensions,
  187. forceNodeFilesystemAPI = options.forceNodeFilesystemAPI,
  188. ignore = options.ignore,
  189. rootDir = options.rootDir,
  190. roots = options.roots;
  191. return new Promise(resolve => {
  192. const callback = list => {
  193. const files = new Map();
  194. const removedFiles = new Map(data.files);
  195. list.forEach(fileData => {
  196. const _fileData = _slicedToArray(fileData, 3),
  197. filePath = _fileData[0],
  198. mtime = _fileData[1],
  199. size = _fileData[2];
  200. const relativeFilePath = fastPath.relative(rootDir, filePath);
  201. const existingFile = data.files.get(relativeFilePath);
  202. if (existingFile && existingFile[_constants.default.MTIME] === mtime) {
  203. files.set(relativeFilePath, existingFile);
  204. } else {
  205. // See ../constants.js; SHA-1 will always be null and fulfilled later.
  206. files.set(relativeFilePath, ['', mtime, size, 0, '', null]);
  207. }
  208. removedFiles.delete(relativeFilePath);
  209. });
  210. data.files = files;
  211. resolve({
  212. hasteMap: data,
  213. removedFiles
  214. });
  215. };
  216. if (forceNodeFilesystemAPI || process.platform === 'win32') {
  217. find(roots, extensions, ignore, callback);
  218. } else {
  219. findNative(roots, extensions, ignore, callback);
  220. }
  221. });
  222. };