1 | 'use strict';
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports.NohoistResolver = exports.HoistManifest = undefined;
|
7 |
|
8 | var _extends2;
|
9 |
|
10 | function _load_extends() {
|
11 | return _extends2 = _interopRequireDefault(require('babel-runtime/helpers/extends'));
|
12 | }
|
13 |
|
14 | var _config;
|
15 |
|
16 | function _load_config() {
|
17 | return _config = _interopRequireDefault(require('./config.js'));
|
18 | }
|
19 |
|
20 | var _misc;
|
21 |
|
22 | function _load_misc() {
|
23 | return _misc = require('./util/misc.js');
|
24 | }
|
25 |
|
26 | var _micromatch;
|
27 |
|
28 | function _load_micromatch() {
|
29 | return _micromatch = _interopRequireDefault(require('micromatch'));
|
30 | }
|
31 |
|
32 | var _workspaceLayout2;
|
33 |
|
34 | function _load_workspaceLayout() {
|
35 | return _workspaceLayout2 = _interopRequireDefault(require('./workspace-layout.js'));
|
36 | }
|
37 |
|
38 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
39 |
|
40 | const invariant = require('invariant');
|
41 |
|
42 | const path = require('path');
|
43 |
|
44 | let historyCounter = 0;
|
45 |
|
46 | const LINK_TYPES = new Set(['workspace', 'link']);
|
47 | class HoistManifest {
|
48 | constructor(key, parts, pkg, loc, isDirectRequire, isRequired, isIncompatible) {
|
49 | this.isDirectRequire = isDirectRequire;
|
50 | this.isRequired = isRequired;
|
51 | this.isIncompatible = isIncompatible;
|
52 |
|
53 | this.loc = loc;
|
54 | this.pkg = pkg;
|
55 | this.key = key;
|
56 | this.parts = parts;
|
57 | this.originalKey = key;
|
58 | this.previousPaths = [];
|
59 |
|
60 | this.history = [];
|
61 | this.addHistory(`Start position = ${key}`);
|
62 |
|
63 | this.isNohoist = false;
|
64 | this.originalParentPath = '';
|
65 |
|
66 | this.shallowPaths = [];
|
67 | this.isShallow = false;
|
68 | }
|
69 |
|
70 |
|
71 |
|
72 |
|
73 |
|
74 |
|
75 |
|
76 | addHistory(msg) {
|
77 | this.history.push(`${++historyCounter}: ${msg}`);
|
78 | }
|
79 | }
|
80 |
|
81 | exports.HoistManifest = HoistManifest;
|
82 | class PackageHoister {
|
83 | constructor(config, resolver, { ignoreOptional, workspaceLayout } = {}) {
|
84 | this.resolver = resolver;
|
85 | this.config = config;
|
86 |
|
87 | this.ignoreOptional = ignoreOptional;
|
88 |
|
89 | this.taintedKeys = new Map();
|
90 | this.levelQueue = [];
|
91 | this.tree = new Map();
|
92 |
|
93 | this.workspaceLayout = workspaceLayout;
|
94 |
|
95 | this.nohoistResolver = new NohoistResolver(config, resolver);
|
96 | }
|
97 |
|
98 | |
99 |
|
100 |
|
101 |
|
102 | taintKey(key, info) {
|
103 | const existingTaint = this.taintedKeys.get(key);
|
104 | if (existingTaint && existingTaint.loc !== info.loc) {
|
105 | return false;
|
106 | } else {
|
107 | this.taintedKeys.set(key, info);
|
108 | return true;
|
109 | }
|
110 | }
|
111 |
|
112 | |
113 |
|
114 |
|
115 |
|
116 | implodeKey(parts) {
|
117 | return parts.join('#');
|
118 | }
|
119 |
|
120 | |
121 |
|
122 |
|
123 |
|
124 | seed(patterns) {
|
125 | this.prepass(patterns);
|
126 |
|
127 | for (var _iterator = this.resolver.dedupePatterns(patterns), _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
|
128 | var _ref;
|
129 |
|
130 | if (_isArray) {
|
131 | if (_i >= _iterator.length) break;
|
132 | _ref = _iterator[_i++];
|
133 | } else {
|
134 | _i = _iterator.next();
|
135 | if (_i.done) break;
|
136 | _ref = _i.value;
|
137 | }
|
138 |
|
139 | const pattern = _ref;
|
140 |
|
141 | this._seed(pattern, { isDirectRequire: true });
|
142 | }
|
143 |
|
144 | while (true) {
|
145 | let queue = this.levelQueue;
|
146 | if (!queue.length) {
|
147 | this._propagateRequired();
|
148 | return;
|
149 | }
|
150 |
|
151 | this.levelQueue = [];
|
152 |
|
153 |
|
154 | queue = queue.sort(([aPattern], [bPattern]) => {
|
155 | return (0, (_misc || _load_misc()).sortAlpha)(aPattern, bPattern);
|
156 | });
|
157 |
|
158 |
|
159 | let sortedQueue = [];
|
160 | const availableSet = new Set();
|
161 |
|
162 | let hasChanged = true;
|
163 | while (queue.length > 0 && hasChanged) {
|
164 | hasChanged = false;
|
165 |
|
166 | const queueCopy = queue;
|
167 | queue = [];
|
168 | for (let t = 0; t < queueCopy.length; ++t) {
|
169 | const queueItem = queueCopy[t];
|
170 | const pattern = queueItem[0];
|
171 | const pkg = this.resolver.getStrictResolvedPattern(pattern);
|
172 |
|
173 | const peerDependencies = Object.keys(pkg.peerDependencies || {});
|
174 | const areDependenciesFulfilled = peerDependencies.every(peerDependency => availableSet.has(peerDependency));
|
175 |
|
176 | if (areDependenciesFulfilled) {
|
177 |
|
178 | sortedQueue.push(queueItem);
|
179 |
|
180 |
|
181 | availableSet.add(pattern);
|
182 |
|
183 |
|
184 | hasChanged = true;
|
185 | } else {
|
186 | queue.push(queueItem);
|
187 | }
|
188 | }
|
189 | }
|
190 |
|
191 |
|
192 |
|
193 |
|
194 | sortedQueue = sortedQueue.concat(queue);
|
195 |
|
196 | for (var _iterator2 = sortedQueue, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
|
197 | var _ref3;
|
198 |
|
199 | if (_isArray2) {
|
200 | if (_i2 >= _iterator2.length) break;
|
201 | _ref3 = _iterator2[_i2++];
|
202 | } else {
|
203 | _i2 = _iterator2.next();
|
204 | if (_i2.done) break;
|
205 | _ref3 = _i2.value;
|
206 | }
|
207 |
|
208 | const _ref2 = _ref3;
|
209 | const pattern = _ref2[0];
|
210 | const parent = _ref2[1];
|
211 |
|
212 | const info = this._seed(pattern, { isDirectRequire: false, parent });
|
213 | if (info) {
|
214 | this.hoist(info);
|
215 | }
|
216 | }
|
217 | }
|
218 | }
|
219 |
|
220 | |
221 |
|
222 |
|
223 |
|
224 | _seed(pattern, { isDirectRequire, parent }) {
|
225 |
|
226 | const pkg = this.resolver.getStrictResolvedPattern(pattern);
|
227 | const ref = pkg._reference;
|
228 | invariant(ref, 'expected reference');
|
229 |
|
230 |
|
231 | let parentParts = [];
|
232 |
|
233 | const isIncompatible = ref.incompatible;
|
234 | const isMarkedAsOptional = ref.optional && this.ignoreOptional;
|
235 |
|
236 | let isRequired = isDirectRequire && !ref.ignore && !isIncompatible && !isMarkedAsOptional;
|
237 |
|
238 | if (parent) {
|
239 | if (!this.tree.get(parent.key)) {
|
240 | return null;
|
241 | }
|
242 |
|
243 |
|
244 | if (!isDirectRequire && !isIncompatible && parent.isRequired && !isMarkedAsOptional) {
|
245 | isRequired = true;
|
246 | }
|
247 | parentParts = parent.parts;
|
248 | }
|
249 |
|
250 |
|
251 | const loc = this.config.generateModuleCachePath(ref);
|
252 | const parts = parentParts.concat(pkg.name);
|
253 | const key = this.implodeKey(parts);
|
254 | const info = new HoistManifest(key, parts, pkg, loc, isDirectRequire, isRequired, isIncompatible);
|
255 |
|
256 | this.nohoistResolver.initNohoist(info, parent);
|
257 |
|
258 | this.tree.set(key, info);
|
259 | this.taintKey(key, info);
|
260 |
|
261 |
|
262 | const pushed = new Set();
|
263 | for (var _iterator3 = ref.dependencies, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
|
264 | var _ref4;
|
265 |
|
266 | if (_isArray3) {
|
267 | if (_i3 >= _iterator3.length) break;
|
268 | _ref4 = _iterator3[_i3++];
|
269 | } else {
|
270 | _i3 = _iterator3.next();
|
271 | if (_i3.done) break;
|
272 | _ref4 = _i3.value;
|
273 | }
|
274 |
|
275 | const depPattern = _ref4;
|
276 |
|
277 | if (!pushed.has(depPattern)) {
|
278 | this.levelQueue.push([depPattern, info]);
|
279 | pushed.add(depPattern);
|
280 | }
|
281 | }
|
282 |
|
283 | return info;
|
284 | }
|
285 |
|
286 | |
287 |
|
288 |
|
289 |
|
290 | _propagateRequired() {
|
291 |
|
292 | const toVisit = [];
|
293 |
|
294 |
|
295 | for (var _iterator4 = this.tree.entries(), _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) {
|
296 | var _ref5;
|
297 |
|
298 | if (_isArray4) {
|
299 | if (_i4 >= _iterator4.length) break;
|
300 | _ref5 = _iterator4[_i4++];
|
301 | } else {
|
302 | _i4 = _iterator4.next();
|
303 | if (_i4.done) break;
|
304 | _ref5 = _i4.value;
|
305 | }
|
306 |
|
307 | const entry = _ref5;
|
308 |
|
309 | if (entry[1].isRequired) {
|
310 | toVisit.push(entry[1]);
|
311 | }
|
312 | }
|
313 |
|
314 |
|
315 | while (toVisit.length) {
|
316 | const info = toVisit.shift();
|
317 | const ref = info.pkg._reference;
|
318 | invariant(ref, 'expected reference');
|
319 |
|
320 | for (var _iterator5 = ref.dependencies, _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) {
|
321 | var _ref6;
|
322 |
|
323 | if (_isArray5) {
|
324 | if (_i5 >= _iterator5.length) break;
|
325 | _ref6 = _iterator5[_i5++];
|
326 | } else {
|
327 | _i5 = _iterator5.next();
|
328 | if (_i5.done) break;
|
329 | _ref6 = _i5.value;
|
330 | }
|
331 |
|
332 | const depPattern = _ref6;
|
333 |
|
334 | const depinfo = this._lookupDependency(info, depPattern);
|
335 |
|
336 | if (!depinfo) {
|
337 | continue;
|
338 | }
|
339 |
|
340 | const depRef = depinfo.pkg._reference;
|
341 |
|
342 |
|
343 |
|
344 |
|
345 | const isMarkedAsOptional = depRef && depRef.optional && this.ignoreOptional && !(info.isRequired && depRef.hint !== 'optional');
|
346 |
|
347 | if (!depinfo.isRequired && !depinfo.isIncompatible && !isMarkedAsOptional) {
|
348 | depinfo.isRequired = true;
|
349 | depinfo.addHistory(`Mark as non-ignored because of usage by ${info.key}`);
|
350 | toVisit.push(depinfo);
|
351 | }
|
352 | }
|
353 | }
|
354 | }
|
355 |
|
356 | |
357 |
|
358 |
|
359 |
|
360 | _lookupDependency(info, depPattern) {
|
361 |
|
362 | const pkg = this.resolver.getStrictResolvedPattern(depPattern);
|
363 | const ref = pkg._reference;
|
364 | invariant(ref, 'expected reference');
|
365 |
|
366 |
|
367 | for (let i = info.parts.length; i >= 0; i--) {
|
368 | const checkParts = info.parts.slice(0, i).concat(pkg.name);
|
369 | const checkKey = this.implodeKey(checkParts);
|
370 | const existing = this.tree.get(checkKey);
|
371 | if (existing) {
|
372 | return existing;
|
373 | }
|
374 | }
|
375 |
|
376 | return null;
|
377 | }
|
378 |
|
379 | |
380 |
|
381 |
|
382 |
|
383 | getNewParts(key, info, parts) {
|
384 | let stepUp = false;
|
385 |
|
386 | const highestHoistingPoint = this.nohoistResolver.highestHoistingPoint(info) || 0;
|
387 | const fullKey = this.implodeKey(parts);
|
388 | const stack = [];
|
389 | const name = parts.pop();
|
390 |
|
391 | if (info.isNohoist) {
|
392 | info.addHistory(`Marked as nohoist, will not be hoisted above '${parts[highestHoistingPoint]}'`);
|
393 | }
|
394 |
|
395 | for (let i = parts.length - 1; i >= highestHoistingPoint; i--) {
|
396 | const checkParts = parts.slice(0, i).concat(name);
|
397 | const checkKey = this.implodeKey(checkParts);
|
398 | info.addHistory(`Looked at ${checkKey} for a match`);
|
399 |
|
400 | const existing = this.tree.get(checkKey);
|
401 |
|
402 | if (existing) {
|
403 | if (existing.loc === info.loc) {
|
404 |
|
405 | if (!existing.isRequired && info.isRequired) {
|
406 | existing.addHistory(`Deduped ${fullKey} to this item, marking as required`);
|
407 | existing.isRequired = true;
|
408 | } else {
|
409 | existing.addHistory(`Deduped ${fullKey} to this item`);
|
410 | }
|
411 |
|
412 | return { parts: checkParts, duplicate: true };
|
413 | } else {
|
414 |
|
415 | info.addHistory(`Found a collision at ${checkKey}`);
|
416 | break;
|
417 | }
|
418 | }
|
419 |
|
420 | const existingTaint = this.taintedKeys.get(checkKey);
|
421 | if (existingTaint && existingTaint.loc !== info.loc) {
|
422 | info.addHistory(`Broken by ${checkKey}`);
|
423 | break;
|
424 | }
|
425 | }
|
426 |
|
427 | const peerDependencies = Object.keys(info.pkg.peerDependencies || {});
|
428 |
|
429 |
|
430 | hoistLoop: while (parts.length > highestHoistingPoint) {
|
431 |
|
432 | for (var _iterator6 = peerDependencies, _isArray6 = Array.isArray(_iterator6), _i6 = 0, _iterator6 = _isArray6 ? _iterator6 : _iterator6[Symbol.iterator]();;) {
|
433 | var _ref7;
|
434 |
|
435 | if (_isArray6) {
|
436 | if (_i6 >= _iterator6.length) break;
|
437 | _ref7 = _iterator6[_i6++];
|
438 | } else {
|
439 | _i6 = _iterator6.next();
|
440 | if (_i6.done) break;
|
441 | _ref7 = _i6.value;
|
442 | }
|
443 |
|
444 | const peerDependency = _ref7;
|
445 |
|
446 | const checkParts = parts.concat(peerDependency);
|
447 | const checkKey = this.implodeKey(checkParts);
|
448 | info.addHistory(`Looked at ${checkKey} for a peer dependency match`);
|
449 |
|
450 | const existing = this.tree.get(checkKey);
|
451 |
|
452 | if (existing) {
|
453 | info.addHistory(`Found a peer dependency requirement at ${checkKey}`);
|
454 | break hoistLoop;
|
455 | }
|
456 | }
|
457 |
|
458 | const checkParts = parts.concat(name);
|
459 | const checkKey = this.implodeKey(checkParts);
|
460 |
|
461 |
|
462 | const existing = this.tree.get(checkKey);
|
463 | if (existing) {
|
464 | stepUp = true;
|
465 | break;
|
466 | }
|
467 |
|
468 |
|
469 |
|
470 | if (key !== checkKey && this.taintedKeys.has(checkKey)) {
|
471 | stepUp = true;
|
472 | break;
|
473 | }
|
474 |
|
475 |
|
476 | stack.push(parts.pop());
|
477 | }
|
478 |
|
479 |
|
480 | parts.push(name);
|
481 |
|
482 |
|
483 | const isValidPosition = parts => {
|
484 |
|
485 | if (parts.length <= highestHoistingPoint) {
|
486 | return false;
|
487 | }
|
488 | const key = this.implodeKey(parts);
|
489 | const existing = this.tree.get(key);
|
490 | if (existing && existing.loc === info.loc) {
|
491 | return true;
|
492 | }
|
493 |
|
494 |
|
495 | const existingTaint = this.taintedKeys.get(key);
|
496 | if (existingTaint && existingTaint.loc !== info.loc) {
|
497 | return false;
|
498 | }
|
499 |
|
500 | return true;
|
501 | };
|
502 |
|
503 |
|
504 |
|
505 | if (!isValidPosition(parts)) {
|
506 | stepUp = true;
|
507 | }
|
508 |
|
509 |
|
510 | while (stepUp && stack.length) {
|
511 | info.addHistory(`Stepping up from ${this.implodeKey(parts)}`);
|
512 |
|
513 | parts.pop();
|
514 | parts.push(stack.pop(), name);
|
515 |
|
516 | if (isValidPosition(parts)) {
|
517 | info.addHistory(`Found valid position ${this.implodeKey(parts)}`);
|
518 | stepUp = false;
|
519 | }
|
520 | }
|
521 |
|
522 | return { parts, duplicate: false };
|
523 | }
|
524 |
|
525 | |
526 |
|
527 |
|
528 |
|
529 | hoist(info) {
|
530 | const oldKey = info.key,
|
531 | rawParts = info.parts;
|
532 |
|
533 |
|
534 |
|
535 | this.tree.delete(oldKey);
|
536 |
|
537 | var _getNewParts = this.getNewParts(oldKey, info, rawParts.slice());
|
538 |
|
539 | const parts = _getNewParts.parts,
|
540 | duplicate = _getNewParts.duplicate;
|
541 |
|
542 |
|
543 | const newKey = this.implodeKey(parts);
|
544 | if (duplicate) {
|
545 | info.addHistory(`Satisfied from above by ${newKey}`);
|
546 | this.declareRename(info, rawParts, parts);
|
547 | this.updateHoistHistory(this.nohoistResolver._originalPath(info), this.implodeKey(parts));
|
548 | return;
|
549 | }
|
550 |
|
551 |
|
552 | if (oldKey === newKey) {
|
553 | info.addHistory(`Didn't hoist - see reason above`);
|
554 | this.setKey(info, oldKey, rawParts);
|
555 | return;
|
556 | }
|
557 |
|
558 |
|
559 | this.declareRename(info, rawParts, parts);
|
560 | this.setKey(info, newKey, parts);
|
561 | }
|
562 |
|
563 | |
564 |
|
565 |
|
566 |
|
567 | declareRename(info, oldParts, newParts) {
|
568 |
|
569 | this.taintParents(info, oldParts.slice(0, -1), newParts.length - 1);
|
570 | }
|
571 |
|
572 | |
573 |
|
574 |
|
575 |
|
576 | taintParents(info, processParts, start) {
|
577 | for (let i = start; i < processParts.length; i++) {
|
578 | const parts = processParts.slice(0, i).concat(info.pkg.name);
|
579 | const key = this.implodeKey(parts);
|
580 |
|
581 | if (this.taintKey(key, info)) {
|
582 | info.addHistory(`Tainted ${key} to prevent collisions`);
|
583 | }
|
584 | }
|
585 | }
|
586 |
|
587 | updateHoistHistory(fromPath, toKey) {
|
588 | const info = this.tree.get(toKey);
|
589 | invariant(info, `expect to find hoist-to ${toKey}`);
|
590 | info.previousPaths.push(fromPath);
|
591 | }
|
592 |
|
593 | |
594 |
|
595 |
|
596 |
|
597 | setKey(info, newKey, parts) {
|
598 | const oldKey = info.key;
|
599 |
|
600 | info.key = newKey;
|
601 | info.parts = parts;
|
602 | this.tree.set(newKey, info);
|
603 |
|
604 | if (oldKey === newKey) {
|
605 | return;
|
606 | }
|
607 |
|
608 | const fromInfo = this.tree.get(newKey);
|
609 | invariant(fromInfo, `expect to find hoist-from ${newKey}`);
|
610 | info.previousPaths.push(this.nohoistResolver._originalPath(fromInfo));
|
611 | info.addHistory(`New position = ${newKey}`);
|
612 | }
|
613 |
|
614 | |
615 |
|
616 |
|
617 |
|
618 |
|
619 | prepass(patterns) {
|
620 | patterns = this.resolver.dedupePatterns(patterns).sort();
|
621 |
|
622 | const visited = new Map();
|
623 |
|
624 | const occurences = {};
|
625 |
|
626 |
|
627 | const visitAdd = (pkg, ancestry, pattern) => {
|
628 | const versions = occurences[pkg.name] = occurences[pkg.name] || {};
|
629 | const version = versions[pkg.version] = versions[pkg.version] || {
|
630 | occurences: new Set(),
|
631 | pattern
|
632 | };
|
633 |
|
634 | if (ancestry.length) {
|
635 | version.occurences.add(ancestry[ancestry.length - 1]);
|
636 | }
|
637 | };
|
638 |
|
639 |
|
640 | const add = (pattern, ancestry, ancestryPatterns) => {
|
641 | const pkg = this.resolver.getStrictResolvedPattern(pattern);
|
642 | if (ancestry.indexOf(pkg) >= 0) {
|
643 |
|
644 | return;
|
645 | }
|
646 |
|
647 | let visitedPattern = visited.get(pattern);
|
648 |
|
649 | if (visitedPattern) {
|
650 |
|
651 |
|
652 | visitedPattern.forEach(visitPkg => {
|
653 | visitAdd(visitPkg.pkg, visitPkg.ancestry, visitPkg.pattern);
|
654 | });
|
655 |
|
656 | visitAdd(pkg, ancestry, pattern);
|
657 |
|
658 | return;
|
659 | }
|
660 |
|
661 | const ref = pkg._reference;
|
662 | invariant(ref, 'expected reference');
|
663 |
|
664 | visitAdd(pkg, ancestry, pattern);
|
665 |
|
666 | for (var _iterator7 = ref.dependencies, _isArray7 = Array.isArray(_iterator7), _i7 = 0, _iterator7 = _isArray7 ? _iterator7 : _iterator7[Symbol.iterator]();;) {
|
667 | var _ref8;
|
668 |
|
669 | if (_isArray7) {
|
670 | if (_i7 >= _iterator7.length) break;
|
671 | _ref8 = _iterator7[_i7++];
|
672 | } else {
|
673 | _i7 = _iterator7.next();
|
674 | if (_i7.done) break;
|
675 | _ref8 = _i7.value;
|
676 | }
|
677 |
|
678 | const depPattern = _ref8;
|
679 |
|
680 | const depAncestry = ancestry.concat(pkg);
|
681 | const depAncestryPatterns = ancestryPatterns.concat(depPattern);
|
682 | add(depPattern, depAncestry, depAncestryPatterns);
|
683 | }
|
684 |
|
685 | visitedPattern = visited.get(pattern) || [];
|
686 | visited.set(pattern, visitedPattern);
|
687 | visitedPattern.push({ pkg, ancestry, pattern });
|
688 |
|
689 | ancestryPatterns.forEach(ancestryPattern => {
|
690 | const visitedAncestryPattern = visited.get(ancestryPattern);
|
691 | if (visitedAncestryPattern) {
|
692 | visitedAncestryPattern.push({ pkg, ancestry, pattern });
|
693 | }
|
694 | });
|
695 | };
|
696 |
|
697 |
|
698 | const rootPackageNames = new Set();
|
699 | for (var _iterator8 = patterns, _isArray8 = Array.isArray(_iterator8), _i8 = 0, _iterator8 = _isArray8 ? _iterator8 : _iterator8[Symbol.iterator]();;) {
|
700 | var _ref9;
|
701 |
|
702 | if (_isArray8) {
|
703 | if (_i8 >= _iterator8.length) break;
|
704 | _ref9 = _iterator8[_i8++];
|
705 | } else {
|
706 | _i8 = _iterator8.next();
|
707 | if (_i8.done) break;
|
708 | _ref9 = _i8.value;
|
709 | }
|
710 |
|
711 | const pattern = _ref9;
|
712 |
|
713 | const pkg = this.resolver.getStrictResolvedPattern(pattern);
|
714 | rootPackageNames.add(pkg.name);
|
715 | add(pattern, [], []);
|
716 | }
|
717 |
|
718 | for (var _iterator9 = Object.keys(occurences).sort(), _isArray9 = Array.isArray(_iterator9), _i9 = 0, _iterator9 = _isArray9 ? _iterator9 : _iterator9[Symbol.iterator]();;) {
|
719 | var _ref10;
|
720 |
|
721 | if (_isArray9) {
|
722 | if (_i9 >= _iterator9.length) break;
|
723 | _ref10 = _iterator9[_i9++];
|
724 | } else {
|
725 | _i9 = _iterator9.next();
|
726 | if (_i9.done) break;
|
727 | _ref10 = _i9.value;
|
728 | }
|
729 |
|
730 | const packageName = _ref10;
|
731 |
|
732 | const versionOccurences = occurences[packageName];
|
733 | const versions = Object.keys(versionOccurences);
|
734 |
|
735 | if (versions.length === 1) {
|
736 |
|
737 | continue;
|
738 | }
|
739 |
|
740 | if (this.tree.get(packageName)) {
|
741 |
|
742 | continue;
|
743 | }
|
744 |
|
745 | if (rootPackageNames.has(packageName)) {
|
746 |
|
747 | continue;
|
748 | }
|
749 |
|
750 | let mostOccurenceCount;
|
751 | let mostOccurencePattern;
|
752 | for (var _iterator10 = Object.keys(versionOccurences).sort(), _isArray10 = Array.isArray(_iterator10), _i10 = 0, _iterator10 = _isArray10 ? _iterator10 : _iterator10[Symbol.iterator]();;) {
|
753 | var _ref11;
|
754 |
|
755 | if (_isArray10) {
|
756 | if (_i10 >= _iterator10.length) break;
|
757 | _ref11 = _iterator10[_i10++];
|
758 | } else {
|
759 | _i10 = _iterator10.next();
|
760 | if (_i10.done) break;
|
761 | _ref11 = _i10.value;
|
762 | }
|
763 |
|
764 | const version = _ref11;
|
765 | var _versionOccurences$ve = versionOccurences[version];
|
766 | const occurences = _versionOccurences$ve.occurences,
|
767 | pattern = _versionOccurences$ve.pattern;
|
768 |
|
769 | const occurenceCount = occurences.size;
|
770 |
|
771 | if (!mostOccurenceCount || occurenceCount > mostOccurenceCount) {
|
772 | mostOccurenceCount = occurenceCount;
|
773 | mostOccurencePattern = pattern;
|
774 | }
|
775 | }
|
776 | invariant(mostOccurencePattern, 'expected most occurring pattern');
|
777 | invariant(mostOccurenceCount, 'expected most occurring count');
|
778 |
|
779 |
|
780 | if (mostOccurenceCount > 1) {
|
781 | this._seed(mostOccurencePattern, { isDirectRequire: false });
|
782 | }
|
783 | }
|
784 | }
|
785 |
|
786 | markShallowWorkspaceEntries() {
|
787 | const targetWorkspace = this.config.focusedWorkspaceName;
|
788 | const targetHoistManifest = this.tree.get(targetWorkspace);
|
789 | invariant(targetHoistManifest, `targetHoistManifest from ${targetWorkspace} missing`);
|
790 |
|
791 |
|
792 | const dependentWorkspaces = Array.from(new Set(this._getDependentWorkspaces(targetHoistManifest)));
|
793 |
|
794 | const entries = Array.from(this.tree);
|
795 | entries.forEach(([key, info]) => {
|
796 | const splitPath = key.split('#');
|
797 |
|
798 |
|
799 | const isShallowDependency = dependentWorkspaces.some(w => {
|
800 | if (splitPath[0] !== w) {
|
801 |
|
802 | return false;
|
803 | }
|
804 | if (!splitPath[1]) {
|
805 |
|
806 | return true;
|
807 | }
|
808 |
|
809 | const treeEntry = this.tree.get(w);
|
810 | invariant(treeEntry, 'treeEntry is not defined for ' + w);
|
811 | const pkg = treeEntry.pkg;
|
812 | return !info.isNohoist && (!pkg.devDependencies || !(splitPath[1] in pkg.devDependencies));
|
813 | });
|
814 |
|
815 | if (isShallowDependency) {
|
816 | info.shallowPaths = [null];
|
817 | return;
|
818 | }
|
819 |
|
820 |
|
821 |
|
822 |
|
823 | if (splitPath.length !== 2 || splitPath[0] !== targetWorkspace) {
|
824 | return;
|
825 | }
|
826 | const unhoistedDependency = splitPath[1];
|
827 | const unhoistedInfo = this.tree.get(unhoistedDependency);
|
828 | if (!unhoistedInfo) {
|
829 | return;
|
830 | }
|
831 | dependentWorkspaces.forEach(w => {
|
832 | if (this._packageDependsOnHoistedPackage(w, unhoistedDependency, false)) {
|
833 | unhoistedInfo.shallowPaths.push(w);
|
834 | }
|
835 | });
|
836 | });
|
837 | }
|
838 |
|
839 | _getDependentWorkspaces(parent, allowDevDeps = true, alreadySeen = new Set()) {
|
840 | const parentName = parent.pkg.name;
|
841 | if (alreadySeen.has(parentName)) {
|
842 | return [];
|
843 | }
|
844 |
|
845 | alreadySeen.add(parentName);
|
846 | invariant(this.workspaceLayout, 'missing workspaceLayout');
|
847 | var _workspaceLayout = this.workspaceLayout;
|
848 | const virtualManifestName = _workspaceLayout.virtualManifestName,
|
849 | workspaces = _workspaceLayout.workspaces;
|
850 |
|
851 |
|
852 | const directDependencies = [];
|
853 | const ignored = [];
|
854 | Object.keys(workspaces).forEach(workspace => {
|
855 | if (alreadySeen.has(workspace) || workspace === virtualManifestName) {
|
856 | return;
|
857 | }
|
858 |
|
859 |
|
860 | let info = this.tree.get(`${parentName}#${workspace}`);
|
861 | if (info) {
|
862 | const workspaceVersion = workspaces[workspace].manifest.version;
|
863 | if (info.isNohoist && info.originalParentPath.startsWith(`/${WS_ROOT_ALIAS}/${parentName}`) && info.pkg.version === workspaceVersion) {
|
864 |
|
865 | directDependencies.push(info.key);
|
866 | } else {
|
867 | ignored.push(workspace);
|
868 | }
|
869 | return;
|
870 | }
|
871 |
|
872 | const searchPath = `/${WS_ROOT_ALIAS}/${parentName}`;
|
873 | info = this.tree.get(workspace);
|
874 | invariant(info, 'missing workspace tree entry ' + workspace);
|
875 | if (!info.previousPaths.some(p => p.startsWith(searchPath))) {
|
876 | return;
|
877 | }
|
878 | if (allowDevDeps || !parent.pkg.devDependencies || !(workspace in parent.pkg.devDependencies)) {
|
879 | directDependencies.push(workspace);
|
880 | }
|
881 | });
|
882 |
|
883 | let nested = directDependencies.map(d => {
|
884 | const dependencyEntry = this.tree.get(d);
|
885 | invariant(dependencyEntry, 'missing dependencyEntry ' + d);
|
886 | return this._getDependentWorkspaces(dependencyEntry, false, alreadySeen);
|
887 | });
|
888 | nested = [].concat.apply([], nested);
|
889 |
|
890 | const directDependencyNames = directDependencies.map(d => d.split('#').slice(-1)[0]);
|
891 |
|
892 | return directDependencyNames.concat(nested).filter(w => ignored.indexOf(w) === -1);
|
893 | }
|
894 |
|
895 | _packageDependsOnHoistedPackage(p, hoisted, checkDevDeps = true, checked = new Set()) {
|
896 |
|
897 | if (checked.has(p) || this.tree.has(`${p}#${hoisted}`)) {
|
898 | return false;
|
899 | }
|
900 | checked.add(p);
|
901 | const info = this.tree.get(p);
|
902 | if (!info) {
|
903 | return false;
|
904 | }
|
905 |
|
906 | const pkg = info.pkg;
|
907 | if (!pkg) {
|
908 | return false;
|
909 | }
|
910 |
|
911 | let deps = [];
|
912 | if (pkg.dependencies) {
|
913 | deps = deps.concat(Object.keys(pkg.dependencies));
|
914 | }
|
915 | if (checkDevDeps && pkg.devDependencies) {
|
916 | deps = deps.concat(Object.keys(pkg.devDependencies));
|
917 | }
|
918 |
|
919 | if (deps.indexOf(hoisted) !== -1) {
|
920 | return true;
|
921 | }
|
922 | return deps.some(dep => this._packageDependsOnHoistedPackage(dep, hoisted, false, checked));
|
923 | }
|
924 |
|
925 | |
926 |
|
927 |
|
928 |
|
929 | init() {
|
930 | const flatTree = [];
|
931 |
|
932 |
|
933 | for (var _iterator11 = this.tree.entries(), _isArray11 = Array.isArray(_iterator11), _i11 = 0, _iterator11 = _isArray11 ? _iterator11 : _iterator11[Symbol.iterator]();;) {
|
934 | var _ref13;
|
935 |
|
936 | if (_isArray11) {
|
937 | if (_i11 >= _iterator11.length) break;
|
938 | _ref13 = _iterator11[_i11++];
|
939 | } else {
|
940 | _i11 = _iterator11.next();
|
941 | if (_i11.done) break;
|
942 | _ref13 = _i11.value;
|
943 | }
|
944 |
|
945 | const _ref12 = _ref13;
|
946 | const key = _ref12[0];
|
947 | const info = _ref12[1];
|
948 |
|
949 |
|
950 | const parts = [];
|
951 | const keyParts = key.split('#');
|
952 | const isWorkspaceEntry = this.workspaceLayout && keyParts[0] === this.workspaceLayout.virtualManifestName;
|
953 |
|
954 |
|
955 |
|
956 |
|
957 | if (isWorkspaceEntry && keyParts.length <= 2) {
|
958 | continue;
|
959 | }
|
960 |
|
961 | for (let i = 0; i < keyParts.length; i++) {
|
962 | const key = keyParts.slice(0, i + 1).join('#');
|
963 | const hoisted = this.tree.get(key);
|
964 | invariant(hoisted, `expected hoisted manifest for "${key}"`);
|
965 | parts.push(this.config.getFolder(hoisted.pkg));
|
966 | parts.push(keyParts[i]);
|
967 | }
|
968 |
|
969 |
|
970 |
|
971 |
|
972 |
|
973 | if (this.workspaceLayout && isWorkspaceEntry) {
|
974 | const wspPkg = this.workspaceLayout.workspaces[keyParts[1]];
|
975 | invariant(wspPkg, `expected workspace package to exist for "${keyParts[1]}"`);
|
976 | parts.splice(0, 4, wspPkg.loc);
|
977 | } else {
|
978 | if (this.config.modulesFolder) {
|
979 |
|
980 |
|
981 | parts.splice(0, 1, this.config.modulesFolder);
|
982 | } else {
|
983 |
|
984 | parts.splice(0, 0, this.config.lockfileFolder);
|
985 | }
|
986 | }
|
987 |
|
988 | const shallowLocs = [];
|
989 | info.shallowPaths.forEach(shallowPath => {
|
990 | const shallowCopyParts = parts.slice();
|
991 | shallowCopyParts[0] = this.config.cwd;
|
992 | if (this.config.modulesFolder) {
|
993 |
|
994 | const treeEntry = this.tree.get(keyParts[0]);
|
995 | invariant(treeEntry, 'expected treeEntry for ' + keyParts[0]);
|
996 | const moduleFolderName = this.config.getFolder(treeEntry.pkg);
|
997 | shallowCopyParts.splice(1, 0, moduleFolderName);
|
998 | }
|
999 |
|
1000 | if (shallowPath) {
|
1001 | const targetWorkspace = this.config.focusedWorkspaceName;
|
1002 | const treeEntry = this.tree.get(`${targetWorkspace}#${shallowPath}`) || this.tree.get(shallowPath);
|
1003 | invariant(treeEntry, 'expected treeEntry for ' + shallowPath);
|
1004 | const moduleFolderName = this.config.getFolder(treeEntry.pkg);
|
1005 | shallowCopyParts.splice(1, 0, moduleFolderName, shallowPath);
|
1006 | }
|
1007 | shallowLocs.push(path.join(...shallowCopyParts));
|
1008 | });
|
1009 |
|
1010 | const loc = path.join(...parts);
|
1011 | flatTree.push([loc, info]);
|
1012 | shallowLocs.forEach(shallowLoc => {
|
1013 | const newManifest = (0, (_extends2 || _load_extends()).default)({}, info, { isShallow: true });
|
1014 | flatTree.push([shallowLoc, newManifest]);
|
1015 | });
|
1016 | }
|
1017 |
|
1018 |
|
1019 | const visibleFlatTree = [];
|
1020 | for (var _iterator12 = flatTree, _isArray12 = Array.isArray(_iterator12), _i12 = 0, _iterator12 = _isArray12 ? _iterator12 : _iterator12[Symbol.iterator]();;) {
|
1021 | var _ref15;
|
1022 |
|
1023 | if (_isArray12) {
|
1024 | if (_i12 >= _iterator12.length) break;
|
1025 | _ref15 = _iterator12[_i12++];
|
1026 | } else {
|
1027 | _i12 = _iterator12.next();
|
1028 | if (_i12.done) break;
|
1029 | _ref15 = _i12.value;
|
1030 | }
|
1031 |
|
1032 | const _ref14 = _ref15;
|
1033 | const loc = _ref14[0];
|
1034 | const info = _ref14[1];
|
1035 |
|
1036 | const ref = info.pkg._reference;
|
1037 | invariant(ref, 'expected reference');
|
1038 | if (!info.isRequired) {
|
1039 | info.addHistory('Deleted as this module was ignored');
|
1040 | } else {
|
1041 | visibleFlatTree.push([loc, info]);
|
1042 | }
|
1043 | }
|
1044 | return visibleFlatTree;
|
1045 | }
|
1046 | }
|
1047 |
|
1048 | exports.default = PackageHoister;
|
1049 | const WS_ROOT_ALIAS = '_project_';
|
1050 | class NohoistResolver {
|
1051 | constructor(config, resolver) {
|
1052 | this.initNohoist = (info, parent) => {
|
1053 | let parentNohoistList;
|
1054 | let originalParentPath = info.originalParentPath;
|
1055 |
|
1056 | if (parent) {
|
1057 | parentNohoistList = parent.nohoistList;
|
1058 | originalParentPath = this._originalPath(parent);
|
1059 | } else {
|
1060 | invariant(this._isTopPackage(info), `${info.key} doesn't have parent nor a top package`);
|
1061 | if (info.pkg.name !== this._wsRootPackageName) {
|
1062 | parentNohoistList = this._wsRootNohoistList;
|
1063 | originalParentPath = this._wsRootPackageName || '';
|
1064 | }
|
1065 | }
|
1066 |
|
1067 | info.originalParentPath = originalParentPath;
|
1068 | let nohoistList = this._extractNohoistList(info.pkg, this._originalPath(info)) || [];
|
1069 | if (parentNohoistList) {
|
1070 | nohoistList = nohoistList.concat(parentNohoistList);
|
1071 | }
|
1072 | info.nohoistList = nohoistList.length > 0 ? nohoistList : null;
|
1073 | info.isNohoist = this._isNohoist(info);
|
1074 | };
|
1075 |
|
1076 | this.highestHoistingPoint = info => {
|
1077 | return info.isNohoist && info.parts.length > 1 ? 1 : null;
|
1078 | };
|
1079 |
|
1080 | this._isNohoist = info => {
|
1081 | if (this._isTopPackage(info)) {
|
1082 | return false;
|
1083 | }
|
1084 | if (info.nohoistList && info.nohoistList.length > 0 && (_micromatch || _load_micromatch()).default.any(this._originalPath(info), info.nohoistList)) {
|
1085 | return true;
|
1086 | }
|
1087 | if (this._config.plugnplayEnabled) {
|
1088 | return true;
|
1089 | }
|
1090 | return false;
|
1091 | };
|
1092 |
|
1093 | this._isRootPackage = pkg => {
|
1094 | return pkg.name === this._wsRootPackageName;
|
1095 | };
|
1096 |
|
1097 | this._originalPath = info => {
|
1098 | return this._makePath(info.originalParentPath, info.pkg.name);
|
1099 | };
|
1100 |
|
1101 | this._isTopPackage = info => {
|
1102 | const parentParts = info.parts.slice(0, -1);
|
1103 | const result = !parentParts || parentParts.length <= 0 || parentParts.length === 1 && parentParts[0] === this._wsRootPackageName;
|
1104 | return result;
|
1105 | };
|
1106 |
|
1107 | this._isLink = info => {
|
1108 | return info.pkg._remote != null && LINK_TYPES.has(info.pkg._remote.type);
|
1109 | };
|
1110 |
|
1111 | this._extractNohoistList = (pkg, pathPrefix) => {
|
1112 | let nohoistList;
|
1113 | const ws = this._config.getWorkspaces(pkg);
|
1114 |
|
1115 | if (ws && ws.nohoist) {
|
1116 | nohoistList = ws.nohoist.map(p => this._makePath(pathPrefix, p));
|
1117 | }
|
1118 | return nohoistList;
|
1119 | };
|
1120 |
|
1121 | this._resolver = resolver;
|
1122 | this._config = config;
|
1123 | if (resolver.workspaceLayout) {
|
1124 | this._wsRootPackageName = resolver.workspaceLayout.virtualManifestName;
|
1125 |
|
1126 | var _resolver$workspaceLa = resolver.workspaceLayout.getWorkspaceManifest(this._wsRootPackageName);
|
1127 |
|
1128 | const manifest = _resolver$workspaceLa.manifest;
|
1129 |
|
1130 | this._wsRootNohoistList = this._extractNohoistList(manifest, manifest.name);
|
1131 | }
|
1132 | }
|
1133 |
|
1134 | |
1135 |
|
1136 |
|
1137 |
|
1138 |
|
1139 | |
1140 |
|
1141 |
|
1142 |
|
1143 |
|
1144 |
|
1145 |
|
1146 |
|
1147 |
|
1148 |
|
1149 | _makePath(...args) {
|
1150 | const parts = args.map(s => s === this._wsRootPackageName ? WS_ROOT_ALIAS : s);
|
1151 | const result = parts.join('/');
|
1152 | return result[0] === '/' ? result : '/' + result;
|
1153 | }
|
1154 |
|
1155 |
|
1156 |
|
1157 | }
|
1158 |
|
1159 | exports.NohoistResolver = NohoistResolver; |
\ | No newline at end of file |