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

287 lines (238 loc) 9.54 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; function _bluebird() { const data = require("bluebird"); _bluebird = function () { return data; }; return data; } function _ramda() { const data = _interopRequireDefault(require("ramda")); _ramda = function () { return data; }; return data; } function _utils() { const data = require("../../../utils"); _utils = function () { return data; }; return data; } function _repositories() { const data = require("../../../scope/repositories"); _repositories = function () { return data; }; return data; } function _mergeFiles() { const data = _interopRequireDefault(require("../../../utils/merge-files")); _mergeFiles = function () { return data; }; return data; } function _path() { const data = require("../../../utils/path"); _path = function () { return data; }; return data; } function _generalError() { const data = _interopRequireDefault(require("../../../error/general-error")); _generalError = function () { return data; }; return data; } /** * it's easier to understand with an example. * a component bar/foo has two versions: 0.0.1, 0.0.2. Also, the component was modified locally. * the user is running 'bit checkout 0.0.1 bar/foo' to switch the version of bar/foo to 0.0.1. * * the goal is to rewrite bar/foo to the filesystem as 0.0.1 and keeping the local changes. * in other words, the changes the user did since 0.0.2 should be applied/merged on top of 0.0.1. * * to do the actual merge we use git, specifically `merge-file` command, so we try to use the same * terminology as git. From the command help: * `git merge-file <current-file> <base-file> <other-file> * git merge-file incorporates all changes that lead from the <base-file> to <other-file> into * <current-file>. The result ordinarily goes into <current-file>.` * * according to the example above: * current-file => bar/foo@0.0.1 * base-file => bar/foo@0.0.2 * other-file => bar/foo@0.0.2 + modification */ var _default = /*#__PURE__*/function () { var _threeWayMergeVersions = (0, _bluebird().coroutine)(function* ({ consumer, otherComponent, otherVersion, currentComponent, currentVersion, baseComponent }) { // baseFiles and currentFiles come from the model, therefore their paths include the // sharedOriginallyDir. fsFiles come from the Fs, therefore their paths don't include the // sharedOriginallyDir. // option 1) strip sharedOriginallyDir from baseFiles and currentFiles. the problem is that the // sharedDir can be different if the dependencies were changes for example, as a result, it won't // be possible to compare between the files as the paths are different. // in the previous it was implemented this way and caused a bug, which now has an e2e-test to // block it. see https://github.com/teambit/bit/pull/2070 PR. // option 2) add sharedOriginallyDir to the fsFiles. we must go with this option. const baseFiles = baseComponent.files; const currentFiles = currentComponent.files; const fsFiles = otherComponent.cloneFilesWithSharedDir(); const results = { addFiles: [], modifiedFiles: [], unModifiedFiles: [], overrideFiles: [], hasConflicts: false }; const getFileResult = (fsFile, baseFile, currentFile) => { const filePath = (0, _path().pathNormalizeToLinux)(fsFile.relative); if (!currentFile) { // if !currentFile && !baseFile, the file was created after the last tag // if !currentFile && baseFile, the file was created as part of the last tag // either way, no need to do any calculation, the file should be added // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! results.addFiles.push({ filePath, fsFile }); return; } if (!baseFile) { // if currentFile && !baseFile, the file was deleted as part of the last tag // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! results.overrideFiles.push({ filePath, fsFile }); return; } // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! const fsFileHash = (0, _utils().sha1)(fsFile.contents); const baseFileHash = baseFile.file.hash; const currentFileHash = currentFile.file.hash; if (fsFileHash === currentFileHash) { // no need to check also for fsFileHash === baseFileHash, as long as fs == current, no need to take any action // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! results.unModifiedFiles.push({ filePath, fsFile }); return; } if (fsFileHash === baseFileHash) { // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! results.overrideFiles.push({ filePath, fsFile }); return; } // it was changed in both, there is a chance for conflict // @ts-ignore it's a hack to pass the data, version is not a valid attribute. fsFile.version = otherVersion; // @ts-ignore it's a hack to pass the data, version is not a valid attribute. baseFile.version = otherVersion; // @ts-ignore it's a hack to pass the data, version is not a valid attribute. currentFile.version = currentVersion; // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! results.modifiedFiles.push({ filePath, fsFile, baseFile, currentFile, output: null, conflict: null }); }; fsFiles.forEach(fsFile => { const relativePath = (0, _path().pathNormalizeToLinux)(fsFile.relative); const baseFile = baseFiles.find(file => file.relativePath === relativePath); const currentFile = currentFiles.find(file => file.relativePath === relativePath); getFileResult(fsFile, baseFile, currentFile); }); if (_ramda().default.isEmpty(results.modifiedFiles)) return results; const conflictResults = yield getMergeResults(consumer, results.modifiedFiles); conflictResults.forEach(conflictResult => { // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! const modifiedFile = results.modifiedFiles.find(file => file.filePath === conflictResult.filePath); if (!modifiedFile) throw new (_generalError().default)(`unable to find ${conflictResult.filePath} in modified files array`); // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! modifiedFile.output = conflictResult.output; // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! modifiedFile.conflict = conflictResult.conflict; if (conflictResult.conflict) results.hasConflicts = true; }); return results; }); function threeWayMergeVersions(_x) { return _threeWayMergeVersions.apply(this, arguments); } return threeWayMergeVersions; }(); exports.default = _default; function getMergeResults(_x2, _x3) { return _getMergeResults.apply(this, arguments); } function _getMergeResults() { _getMergeResults = (0, _bluebird().coroutine)(function* (consumer, modifiedFiles) { const tmp = new (_repositories().Tmp)(consumer.scope); const conflictResultsP = modifiedFiles.map( /*#__PURE__*/function () { var _ref = (0, _bluebird().coroutine)(function* (modifiedFile) { // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX! const fsFilePathP = tmp.save(modifiedFile.fsFile.contents); const writeFile = /*#__PURE__*/function () { var _ref2 = (0, _bluebird().coroutine)(function* (file) { const content = yield file.file.load(consumer.scope.objects); // @ts-ignore return tmp.save(content.contents.toString()); }); return function writeFile(_x5) { return _ref2.apply(this, arguments); }; }(); const baseFilePathP = writeFile(modifiedFile.baseFile); const currentFilePathP = writeFile(modifiedFile.currentFile); const [fsFilePath, baseFilePath, currentFilePath] = yield Promise.all([fsFilePathP, baseFilePathP, currentFilePathP]); const mergeFilesParams = { filePath: modifiedFile.filePath, currentFile: { // @ts-ignore label: modifiedFile.currentFile.version, path: currentFilePath }, baseFile: { path: baseFilePath }, otherFile: { // @ts-ignore label: `${modifiedFile.fsFile.version} modified`, path: fsFilePath } }; return (0, _mergeFiles().default)(mergeFilesParams); }); return function (_x4) { return _ref.apply(this, arguments); }; }()); return Promise.all(conflictResultsP); }); return _getMergeResults.apply(this, arguments); }