index.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = void 0;
  6. var _path = _interopRequireDefault(require("path"));
  7. var _fs = require("fs");
  8. var _child_process = require("child_process");
  9. var _helperPluginUtils = require("@babel/helper-plugin-utils");
  10. var _istanbulLibInstrument = require("istanbul-lib-instrument");
  11. var _testExclude = _interopRequireDefault(require("test-exclude"));
  12. var _schema = _interopRequireDefault(require("@istanbuljs/schema"));
  13. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  14. function getRealpath(n) {
  15. try {
  16. return (0, _fs.realpathSync)(n) ||
  17. /* istanbul ignore next */
  18. n;
  19. } catch (e) {
  20. /* istanbul ignore next */
  21. return n;
  22. }
  23. }
  24. const memoize = new Map();
  25. /* istanbul ignore next */
  26. const memosep = _path.default.sep === '/' ? ':' : ';';
  27. function loadNycConfig(cwd, opts) {
  28. let memokey = cwd;
  29. const args = [_path.default.resolve(__dirname, 'load-nyc-config-sync.js'), cwd];
  30. if ('nycrcPath' in opts) {
  31. args.push(opts.nycrcPath);
  32. memokey += memosep + opts.nycrcPath;
  33. }
  34. /* execFileSync is expensive, avoid it if possible! */
  35. if (memoize.has(memokey)) {
  36. return memoize.get(memokey);
  37. }
  38. const result = JSON.parse((0, _child_process.execFileSync)(process.execPath, args));
  39. const error = result['load-nyc-config-sync-error'];
  40. if (error) {
  41. throw new Error(error);
  42. }
  43. const config = { ..._schema.default.defaults.babelPluginIstanbul,
  44. cwd,
  45. ...result
  46. };
  47. memoize.set(memokey, config);
  48. return config;
  49. }
  50. function findConfig(opts) {
  51. const cwd = getRealpath(opts.cwd || process.env.NYC_CWD ||
  52. /* istanbul ignore next */
  53. process.cwd());
  54. const keys = Object.keys(opts);
  55. const ignored = Object.keys(opts).filter(s => s === 'nycrcPath' || s === 'cwd');
  56. if (keys.length > ignored.length) {
  57. // explicitly configuring options in babel
  58. // takes precedence.
  59. return { ..._schema.default.defaults.babelPluginIstanbul,
  60. cwd,
  61. ...opts
  62. };
  63. }
  64. if (ignored.length === 0 && process.env.NYC_CONFIG) {
  65. // defaults were already applied by nyc
  66. return JSON.parse(process.env.NYC_CONFIG);
  67. }
  68. return loadNycConfig(cwd, opts);
  69. }
  70. function makeShouldSkip() {
  71. let exclude;
  72. return function shouldSkip(file, nycConfig) {
  73. if (!exclude || exclude.cwd !== nycConfig.cwd) {
  74. exclude = new _testExclude.default({
  75. cwd: nycConfig.cwd,
  76. include: nycConfig.include,
  77. exclude: nycConfig.exclude,
  78. extension: nycConfig.extension,
  79. // Make sure this is true unless explicitly set to `false`. `undefined` is still `true`.
  80. excludeNodeModules: nycConfig.excludeNodeModules !== false
  81. });
  82. }
  83. return !exclude.shouldInstrument(file);
  84. };
  85. }
  86. var _default = (0, _helperPluginUtils.declare)(api => {
  87. api.assertVersion(7);
  88. const shouldSkip = makeShouldSkip();
  89. const t = api.types;
  90. return {
  91. visitor: {
  92. Program: {
  93. enter(path) {
  94. this.__dv__ = null;
  95. this.nycConfig = findConfig(this.opts);
  96. const realPath = getRealpath(this.file.opts.filename);
  97. if (shouldSkip(realPath, this.nycConfig)) {
  98. return;
  99. }
  100. let {
  101. inputSourceMap
  102. } = this.opts;
  103. if (this.opts.useInlineSourceMaps !== false) {
  104. if (!inputSourceMap && this.file.inputMap) {
  105. inputSourceMap = this.file.inputMap.sourcemap;
  106. }
  107. }
  108. const visitorOptions = {};
  109. Object.entries(_schema.default.defaults.instrumentVisitor).forEach(([name, defaultValue]) => {
  110. if (name in this.nycConfig) {
  111. visitorOptions[name] = this.nycConfig[name];
  112. } else {
  113. visitorOptions[name] = _schema.default.defaults.instrumentVisitor[name];
  114. }
  115. });
  116. this.__dv__ = (0, _istanbulLibInstrument.programVisitor)(t, realPath, { ...visitorOptions,
  117. inputSourceMap
  118. });
  119. this.__dv__.enter(path);
  120. },
  121. exit(path) {
  122. if (!this.__dv__) {
  123. return;
  124. }
  125. const result = this.__dv__.exit(path);
  126. if (this.opts.onCover) {
  127. this.opts.onCover(getRealpath(this.file.opts.filename), result.fileCoverage);
  128. }
  129. }
  130. }
  131. }
  132. };
  133. });
  134. exports.default = _default;