UNPKG

@teambit/lanes

Version:
187 lines (184 loc) • 9.03 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.LaneSwitcher = void 0; function _laneId() { const data = require("@teambit/lane-id"); _laneId = function () { return data; }; return data; } function _componentId() { const data = require("@teambit/component-id"); _componentId = function () { return data; }; return data; } function _bitError() { const data = require("@teambit/bit-error"); _bitError = function () { return data; }; return data; } function _lanesModules() { const data = require("@teambit/lanes.modules.create-lane"); _lanesModules = function () { return data; }; return data; } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } class LaneSwitcher { // populated by `this.populateSwitchProps()`, if default-lane, it's undefined constructor(workspace, logger, switchProps, checkoutProps, lanes) { this.workspace = workspace; this.logger = logger; this.switchProps = switchProps; this.checkoutProps = checkoutProps; this.lanes = lanes; _defineProperty(this, "consumer", void 0); _defineProperty(this, "laneIdToSwitchTo", void 0); // populated by `this.populateSwitchProps()` _defineProperty(this, "laneToSwitchTo", void 0); this.consumer = this.workspace.consumer; } async switch() { this.logger.setStatusLine(`switching lanes`); if (this.workspace.isOnMain()) { await (0, _lanesModules().throwForStagedComponents)(this.workspace); } await this.populateSwitchProps(); const bitMapIds = this.workspace.consumer.bitmapIdsFromCurrentLaneIncludeRemoved; const idsToSwitch = this.switchProps.ids || []; const ids = idsToSwitch.map(id => { const bitMapId = bitMapIds.searchWithoutVersion(id); return bitMapId || id; }); const checkoutProps = _objectSpread(_objectSpread({}, this.checkoutProps), {}, { ids, allowAddingComponentsFromScope: true, versionPerId: await this.workspace.resolveMultipleComponentIds(idsToSwitch), lane: this.laneToSwitchTo }); const results = await this.lanes.checkout.checkout(checkoutProps); await this.saveLanesData(); await this.consumer.onDestroy('lane-switch'); return results; } async populateSwitchProps() { const laneId = await this.consumer.scope.lanes.parseLaneIdFromString(this.switchProps.laneName); const skipFetch = this.switchProps.skipFetch; const localLane = await this.consumer.scope.loadLane(laneId); const getMainIds = async () => { if (!skipFetch) { const allIds = this.workspace.listIds(); try { await this.workspace.scope.legacyScope.scopeImporter.importWithoutDeps(allIds, { cache: false, ignoreMissingHead: true }); } catch (err) { this.logger.consoleWarning(`failed to fetch the latest from the remote, falling back to local state. ${err.message}\nuse --skip-fetch to skip this step.`); } } return this.consumer.getIdsOfDefaultLane(); }; const mainIds = await getMainIds(); if (laneId.isDefault()) { await this.populatePropsAccordingToDefaultLane(); this.switchProps.ids = mainIds; } else { let laneIds; if (skipFetch) { if (!localLane) { throw new (_bitError().BitError)(`unable to switch to lane "${laneId.toString()}" with --skip-fetch: the lane doesn't exist in the local scope. run without --skip-fetch to fetch it from the remote.`); } laneIds = this.populatePropsAccordingToLocalLane(localLane); } else { try { laneIds = await this.populatePropsAccordingToRemoteLane(laneId); } catch (err) { if (!localLane) throw err; this.logger.consoleWarning(`failed to fetch lane "${laneId.toString()}" from the remote, falling back to local state. ${err.message}\nuse --skip-fetch to skip this step.`); laneIds = this.populatePropsAccordingToLocalLane(localLane); } } const idsOnLaneOnly = laneIds.filter(id => !mainIds.find(i => i.isEqualWithoutVersion(id))); const idsOnMainOnly = mainIds.filter(id => !laneIds.find(i => i.isEqualWithoutVersion(id))); this.switchProps.ids = [...idsOnMainOnly, ...laneIds]; this.switchProps.laneBitIds = idsOnLaneOnly; } await this.populateIdsAccordingToPattern(); } async populateIdsAccordingToPattern() { if (!this.switchProps.pattern) { return; } if (this.consumer.bitMap.getAllBitIdsFromAllLanes().length) { // if the workspace is not empty, it's possible that it has components from lane-x, and is now switching // partially to lane-y, while lane-y has the same components as lane-x. in which case, the user ends up with // an invalid state of components from lane-x and lane-y together. throw new (_bitError().BitError)('error: use --pattern only when the workspace is empty'); } const allIds = this.switchProps.ids || []; this.switchProps.ids = await this.workspace.filterIdsFromPoolIdsByPattern(this.switchProps.pattern, allIds); } async populatePropsAccordingToRemoteLane(remoteLaneId) { this.laneIdToSwitchTo = remoteLaneId; this.logger.debug(`populatePropsAccordingToRemoteLane, remoteLaneId: ${remoteLaneId.toString()}`); this.throwForSwitchingToCurrentLane(); const remoteLane = await this.lanes.fetchLaneWithItsComponents(remoteLaneId); this.switchProps.laneName = remoteLaneId.name; this.switchProps.localTrackedLane = this.consumer.scope.lanes.getAliasByLaneId(remoteLaneId) || undefined; this.switchProps.remoteLane = remoteLane; this.laneToSwitchTo = remoteLane; this.logger.debug(`populatePropsAccordingToRemoteLane, completed`); return [...remoteLane.toComponentIds()]; } async populatePropsAccordingToDefaultLane() { this.laneIdToSwitchTo = _laneId().LaneId.from(_laneId().DEFAULT_LANE, this.consumer.scope.name); this.throwForSwitchingToCurrentLane(); } populatePropsAccordingToLocalLane(localLane) { this.laneIdToSwitchTo = localLane.toLaneId(); this.laneToSwitchTo = localLane; this.throwForSwitchingToCurrentLane(); return [...localLane.toComponentIds()]; } throwForSwitchingToCurrentLane() { if (this.consumer.getCurrentLaneId().isEqual(this.laneIdToSwitchTo)) { const laneIdStr = this.laneIdToSwitchTo.isDefault() ? this.laneIdToSwitchTo.name : this.laneIdToSwitchTo.toString(); throw new (_bitError().BitError)(`already checked out to "${laneIdStr}". to be up to date with the remote lane, please run "bit checkout head"`); } } async saveLanesData() { const localLaneName = this.switchProps.alias || this.laneIdToSwitchTo.name; if (this.switchProps.remoteLane) { if (!this.switchProps.localTrackedLane) { this.consumer.scope.lanes.trackLane({ localLane: localLaneName, remoteLane: this.laneIdToSwitchTo.name, remoteScope: this.laneIdToSwitchTo.scope }); } } this.consumer.setCurrentLane(this.laneIdToSwitchTo, !this.laneToSwitchTo?.isNew); this.consumer.bitMap.syncWithIds(_componentId().ComponentIdList.fromArray(this.switchProps.ids || []), _componentId().ComponentIdList.fromArray(this.switchProps.laneBitIds || [])); // If this cache isn't cleared, here's what can happen: // Switching from "lane-dev" to "main": while on "lane-dev", ModelComponent keeps in-memory props // `laneHeadLocal` and `laneHeadRemote`. Methods like `headIncludeRemote()` use them and may return // the lane-dev head instead of the head on main. this.consumer.scope.objects.clearObjectsFromCache(); } } exports.LaneSwitcher = LaneSwitcher; //# sourceMappingURL=switch-lanes.js.map