UNPKG

bit-bin

Version:

<a href="https://opensource.org/licenses/Apache-2.0"><img alt="apache" src="https://img.shields.io/badge/License-Apache%202.0-blue.svg"></a> <a href="https://github.com/teambit/bit/blob/master/CONTRIBUTING.md"><img alt="prs" src="https://img.shields.io/b

374 lines (307 loc) 11.3 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); Object.defineProperty(exports, "__esModule", { value: true }); exports.mergeVersion = mergeVersion; exports.getMergeStrategyInteractive = getMergeStrategyInteractive; exports.getMergeStrategy = getMergeStrategy; exports.FileStatus = exports.MergeOptions = exports.mergeOptionsCli = void 0; function _bluebird() { const data = require("bluebird"); _bluebird = function () { return data; }; return data; } function path() { const data = _interopRequireWildcard(require("path")); path = function () { return data; }; return data; } function _chalk() { const data = _interopRequireDefault(require("chalk")); _chalk = function () { return data; }; return data; } function _bitId() { const data = require("../../../bit-id"); _bitId = function () { return data; }; return data; } function _prompts() { const data = require("../../../prompts"); _prompts = function () { return data; }; return data; } function _path2() { const data = require("../../../utils/path"); _path2 = function () { return data; }; return data; } function _twoWayMerge() { const data = _interopRequireDefault(require("./two-way-merge")); _twoWayMerge = function () { return data; }; return data; } function _generalError() { const data = _interopRequireDefault(require("../../../error/general-error")); _generalError = function () { return data; }; return data; } function _componentWriter() { const data = _interopRequireDefault(require("../../component-ops/component-writer")); _componentWriter = function () { return data; }; return data; } function _repositories() { const data = require("../../../scope/repositories"); _repositories = function () { return data; }; return data; } const mergeOptionsCli = { o: 'ours', t: 'theirs', m: 'manual' }; exports.mergeOptionsCli = mergeOptionsCli; const MergeOptions = { ours: 'ours', theirs: 'theirs', manual: 'manual' }; // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! exports.MergeOptions = MergeOptions; const FileStatus = { merged: _chalk().default.green('auto-merged'), manual: _chalk().default.red('CONFLICT'), updated: _chalk().default.green('updated'), added: _chalk().default.green('added'), overridden: _chalk().default.yellow('overridden'), unchanged: _chalk().default.green('unchanged') }; // fileName is PathLinux. TS doesn't let anything else in the keys other than string and number exports.FileStatus = FileStatus; function mergeVersion(_x, _x2, _x3, _x4) { return _mergeVersion.apply(this, arguments); } function _mergeVersion() { _mergeVersion = (0, _bluebird().coroutine)(function* (consumer, version, ids, mergeStrategy) { const { components } = yield consumer.loadComponents(_bitId().BitIds.fromArray(ids)); const allComponentsStatus = yield getAllComponentsStatus(); const componentWithConflict = allComponentsStatus.find(component => component.mergeResults.hasConflicts); if (componentWithConflict && !mergeStrategy) { mergeStrategy = yield getMergeStrategyInteractive(); } const mergedComponentsP = allComponentsStatus.map(({ id, componentFromFS, mergeResults }) => { return applyVersion(consumer, id, componentFromFS, mergeResults, mergeStrategy); }); const mergedComponents = yield Promise.all(mergedComponentsP); return { components: mergedComponents, version }; function getAllComponentsStatus() { return _getAllComponentsStatus.apply(this, arguments); } function _getAllComponentsStatus() { _getAllComponentsStatus = (0, _bluebird().coroutine)(function* () { const tmp = new (_repositories().Tmp)(consumer.scope); try { const componentsStatus = yield Promise.all(components.map(component => getComponentStatus(consumer, component, version))); yield tmp.clear(); return componentsStatus; } catch (err) { yield tmp.clear(); throw err; } }); return _getAllComponentsStatus.apply(this, arguments); } }); return _mergeVersion.apply(this, arguments); } function getComponentStatus(_x5, _x6, _x7) { return _getComponentStatus.apply(this, arguments); } /** * it doesn't matter whether the component is modified. the idea is to merge the * specified version with the current version. * * 1) when there are conflicts and the strategy is "ours", don't do any change to the component. * * 2) when there are conflicts and the strategy is "theirs", add all files from the specified * version and write the component. * * 3) when there is no conflict or there are conflicts and the strategy is manual, update * component.files. * * it's going to be 2-way merge: * current-file: is the current file. * base-file: empty. * other-file: the specified version. */ function _getComponentStatus() { _getComponentStatus = (0, _bluebird().coroutine)(function* (consumer, component, version) { const componentModel = yield consumer.scope.sources.get(component.id); if (!componentModel) { throw new (_generalError().default)(`component ${component.id.toString()} doesn't have any version yet`); } if (!componentModel.hasVersion(version)) { throw new (_generalError().default)(`component ${component.id.toStringWithoutVersion()} doesn't have version ${version}`); } const existingBitMapId = consumer.bitMap.getBitId(component.id, { ignoreVersion: true }); const currentlyUsedVersion = existingBitMapId.version; if (currentlyUsedVersion === version) { throw new (_generalError().default)(`component ${component.id.toStringWithoutVersion()} is already at version ${version}`); } const otherComponent = yield consumer.loadComponentFromModel(component.id.changeVersion(version)); const mergeResults = yield (0, _twoWayMerge().default)({ consumer, otherComponent, otherVersion: version, currentComponent: component, // $FlowFixMe // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! currentVersion: currentlyUsedVersion }); return { componentFromFS: component, id: component.id, mergeResults }; }); return _getComponentStatus.apply(this, arguments); } function applyVersion(_x8, _x9, _x10, _x11, _x12) { return _applyVersion.apply(this, arguments); } function _applyVersion() { _applyVersion = (0, _bluebird().coroutine)(function* (consumer, id, componentFromFS, mergeResults, mergeStrategy) { const filesStatus = {}; if (mergeResults.hasConflicts && mergeStrategy === MergeOptions.ours) { componentFromFS.files.forEach(file => { // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! filesStatus[(0, _path2().pathNormalizeToLinux)(file.relative)] = FileStatus.unchanged; }); return { id, filesStatus }; } const component = componentFromFS.componentFromModel; if (!component) throw new (_generalError().default)('failed finding the component in the model'); const componentMap = componentFromFS.componentMap; if (!componentMap) throw new (_generalError().default)('applyVersion: componentMap was not found'); const files = componentFromFS.files; component.files = files; files.forEach(file => { // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! filesStatus[(0, _path2().pathNormalizeToLinux)(file.relative)] = FileStatus.unchanged; }); // update files according to the merge results const modifiedStatus = applyModifiedVersion(consumer, files, mergeResults, mergeStrategy); const componentWriter = _componentWriter().default.getInstance({ component, // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! writeToPath: component.files[0].base, // find the current path from the files. (we use the first one but it's the same for all) writeConfig: false, // never override the existing bit.json writePackageJson: false, deleteBitDirContent: false, origin: componentMap.origin, consumer, bitMap: consumer.bitMap, existingComponentMap: componentMap }); yield componentWriter.write(); consumer.bitMap.removeComponent(component.id); componentWriter.origin = componentMap.origin; componentWriter.addComponentToBitMap(componentMap.rootDir); return { id, filesStatus: Object.assign(filesStatus, modifiedStatus) }; }); return _applyVersion.apply(this, arguments); } function applyModifiedVersion(consumer, componentFiles, mergeResults, mergeStrategy) { const filesStatus = {}; mergeResults.modifiedFiles.forEach(file => { const filePath = path().normalize(file.filePath); // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! const foundFile = componentFiles.find(componentFile => componentFile.relative === filePath); if (!foundFile) throw new (_generalError().default)(`file ${filePath} not found`); if (mergeResults.hasConflicts && mergeStrategy === MergeOptions.theirs) { // write the version of otherFile const otherFile = file.otherFile; // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! foundFile.contents = otherFile.contents; filesStatus[file.filePath] = FileStatus.updated; } else if (file.conflict) { // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! foundFile.contents = Buffer.from(file.conflict); filesStatus[file.filePath] = FileStatus.manual; } else if (file.output) { // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! foundFile.contents = Buffer.from(file.output); filesStatus[file.filePath] = FileStatus.merged; } else { throw new (_generalError().default)('file does not have output nor conflict'); } }); mergeResults.addFiles.forEach(file => { const otherFile = file.otherFile; componentFiles.push(otherFile); filesStatus[file.filePath] = FileStatus.added; }); return filesStatus; } function getMergeStrategyInteractive() { return _getMergeStrategyInteractive.apply(this, arguments); } function _getMergeStrategyInteractive() { _getMergeStrategyInteractive = (0, _bluebird().coroutine)(function* () { try { const result = yield (0, _prompts().resolveConflictPrompt)(); // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! return mergeOptionsCli[result.mergeStrategy]; } catch (err) { // probably user clicked ^C throw new (_generalError().default)('the action has been canceled'); } }); return _getMergeStrategyInteractive.apply(this, arguments); } function getMergeStrategy(ours, theirs, manual) { if (ours && theirs || ours && manual || theirs && manual) { throw new (_generalError().default)('please choose only one of the following: ours, theirs or manual'); } if (ours) return MergeOptions.ours; if (theirs) return MergeOptions.theirs; if (manual) return MergeOptions.manual; return null; }