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
404 lines (326 loc) • 13.9 kB
JavaScript
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.applyModifiedVersion = applyModifiedVersion;
exports.default = 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 _pMapSeries() {
const data = _interopRequireDefault(require("p-map-series"));
_pMapSeries = function () {
return data;
};
return data;
}
function _constants() {
const data = require("../../constants");
_constants = function () {
return data;
};
return data;
}
function _path2() {
const data = require("../../utils/path");
_path2 = function () {
return data;
};
return data;
}
function _mergeVersion() {
const data = require("./merge-version");
_mergeVersion = function () {
return data;
};
return data;
}
function _generalError() {
const data = _interopRequireDefault(require("../../error/general-error"));
_generalError = function () {
return data;
};
return data;
}
function _manyComponentsWriter() {
const data = _interopRequireDefault(require("../component-ops/many-components-writer"));
_manyComponentsWriter = function () {
return data;
};
return data;
}
function _repositories() {
const data = require("../../scope/repositories");
_repositories = function () {
return data;
};
return data;
}
var _default = /*#__PURE__*/function () {
var _checkoutVersion = (0, _bluebird().coroutine)(function* (consumer, checkoutProps) {
const {
version,
ids,
promptMergeOptions
} = checkoutProps; // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
const {
components
} = yield consumer.loadComponents(ids);
const allComponentsStatus = yield getAllComponentsStatus();
const componentWithConflict = allComponentsStatus.find(component => component.mergeResults && component.mergeResults.hasConflicts);
if (componentWithConflict) {
if (!promptMergeOptions && !checkoutProps.mergeStrategy) {
throw new (_generalError().default)(`automatic merge has failed for component ${componentWithConflict.id.toStringWithoutVersion()}.\nplease use "--manual" to manually merge changes or use "--theirs / --ours" to choose one of the conflicted versions`);
}
if (!checkoutProps.mergeStrategy) checkoutProps.mergeStrategy = yield (0, _mergeVersion().getMergeStrategyInteractive)();
} // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
const failedComponents = allComponentsStatus.filter(componentStatus => componentStatus.failureMessage) // $FlowFixMe componentStatus.failureMessage is set
.map(componentStatus => ({
id: componentStatus.id,
failureMessage: componentStatus.failureMessage
}));
const succeededComponents = allComponentsStatus.filter(componentStatus => !componentStatus.failureMessage); // do not use Promise.all for applyVersion. otherwise, it'll write all components in parallel,
// which can be an issue when some components are also dependencies of others
const componentsResults = yield (0, _pMapSeries().default)(succeededComponents, ({
id,
componentFromFS,
mergeResults
}) => {
return applyVersion(consumer, id, componentFromFS, mergeResults, checkoutProps);
});
const componentsWithDependencies = componentsResults.map(c => c.component).filter(c => c);
const manyComponentsWriter = new (_manyComponentsWriter().default)({
consumer,
componentsWithDependencies,
installNpmPackages: !checkoutProps.skipNpmInstall,
override: true,
verbose: checkoutProps.verbose,
writeDists: !checkoutProps.ignoreDist,
writeConfig: checkoutProps.writeConfig,
writePackageJson: !checkoutProps.ignorePackageJson
});
yield manyComponentsWriter.writeAll();
const appliedVersionComponents = componentsResults.map(c => c.applyVersionResult);
return {
components: appliedVersionComponents,
version,
failedComponents
};
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, checkoutProps)));
yield tmp.clear(); // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
return componentsStatus;
} catch (err) {
yield tmp.clear();
throw err;
}
});
return _getAllComponentsStatus.apply(this, arguments);
}
});
function checkoutVersion(_x, _x2) {
return _checkoutVersion.apply(this, arguments);
}
return checkoutVersion;
}();
exports.default = _default;
function getComponentStatus(_x3, _x4, _x5) {
return _getComponentStatus.apply(this, arguments);
}
/**
* 1) when the files are modified with conflicts and the strategy is "ours", leave the FS as is
* and update only bitmap id version. (not the componentMap object).
*
* 2) when the files are modified with conflicts and the strategy is "theirs", write the component
* according to id.version.
*
* 3) when files are modified with no conflict or files are modified with conflicts and the
* strategy is manual, load the component according to id.version and update component.files.
* applyModifiedVersion() docs explains what files are updated/added.
*
* 4) when --reset flag is used, write the component according to the bitmap version
*
* Side note:
* Deleted file => if files are in used version but not in the modified one, no need to delete it. (similar to git).
* Added file => if files are not in used version but in the modified one, they'll be under mergeResults.addFiles
*/
function _getComponentStatus() {
_getComponentStatus = (0, _bluebird().coroutine)(function* (consumer, component, checkoutProps) {
const {
version,
latestVersion,
reset
} = checkoutProps;
const componentModel = yield consumer.scope.getModelComponentIfExist(component.id);
const componentStatus = {
id: component.id
};
const returnFailure = msg => {
componentStatus.failureMessage = msg;
return componentStatus;
};
if (!componentModel) {
return returnFailure(`component ${component.id.toString()} doesn't have any version yet`);
}
const getNewVersion = () => {
// @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
if (reset) return component.id.version; // $FlowFixMe if !reset the version is defined
// @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
return latestVersion ? componentModel.latest() : version;
};
const newVersion = getNewVersion();
if (version && !latestVersion && !componentModel.hasVersion(version)) {
return returnFailure(`component ${component.id.toStringWithoutVersion()} doesn't have version ${version}`);
}
const existingBitMapId = consumer.bitMap.getBitId(component.id, {
ignoreVersion: true
});
const currentlyUsedVersion = existingBitMapId.version;
if (version && currentlyUsedVersion === version) {
// it won't be relevant for 'reset' as it doesn't have a version
return returnFailure(`component ${component.id.toStringWithoutVersion()} is already at version ${version}`);
}
if (latestVersion && currentlyUsedVersion === newVersion) {
return returnFailure(`component ${component.id.toStringWithoutVersion()} is already at the latest version, which is ${newVersion}`);
} // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
const baseComponent = yield componentModel.loadVersion(currentlyUsedVersion, consumer.scope.objects);
const isModified = yield consumer.isComponentModified(baseComponent, component);
if (!isModified && reset) {
return returnFailure(`component ${component.id.toStringWithoutVersion()} is not modified`);
}
let mergeResults;
if (isModified && version) {
const currentComponent = yield componentModel.loadVersion(newVersion, consumer.scope.objects);
mergeResults = yield (0, _mergeVersion().threeWayMerge)({
consumer,
otherComponent: component,
// @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
otherVersion: currentlyUsedVersion,
currentComponent,
currentVersion: newVersion,
baseComponent
});
}
const versionRef = componentModel.versions[newVersion];
const componentVersion = yield consumer.scope.getObject(versionRef.hash);
const newId = component.id.changeVersion(newVersion); // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
return {
componentFromFS: component,
componentFromModel: componentVersion,
id: newId,
mergeResults
};
});
return _getComponentStatus.apply(this, arguments);
}
function applyVersion(_x6, _x7, _x8, _x9, _x10) {
return _applyVersion.apply(this, arguments);
}
/**
* relevant only when
* 1) there is no conflict => add files from mergeResults: addFiles, overrideFiles and modifiedFiles.output.
* 2) there is conflict and mergeStrategy is manual => add files from mergeResults: addFiles, overrideFiles and modifiedFiles.conflict.
*
* this function only updates the files content, it doesn't write the files
*/
function _applyVersion() {
_applyVersion = (0, _bluebird().coroutine)(function* (consumer, id, componentFromFS, mergeResults, checkoutProps) {
const {
mergeStrategy
} = checkoutProps;
const filesStatus = {};
if (mergeResults && mergeResults.hasConflicts && mergeStrategy === _mergeVersion().MergeOptions.ours) {
componentFromFS.files.forEach(file => {
// @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
filesStatus[(0, _path2().pathNormalizeToLinux)(file.relative)] = _mergeVersion().FileStatus.unchanged;
});
consumer.bitMap.updateComponentId(id);
return {
applyVersionResult: {
id,
filesStatus
}
};
}
const componentWithDependencies = yield consumer.loadComponentWithDependenciesFromModel(id);
const componentMap = componentFromFS.componentMap;
if (!componentMap) throw new (_generalError().default)('applyVersion: componentMap was not found');
if (componentMap.origin === _constants().COMPONENT_ORIGINS.AUTHORED && !id.scope) {
componentWithDependencies.dependencies = [];
componentWithDependencies.devDependencies = [];
}
const files = componentWithDependencies.component.files;
files.forEach(file => {
// @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
filesStatus[(0, _path2().pathNormalizeToLinux)(file.relative)] = _mergeVersion().FileStatus.updated;
});
let modifiedStatus = {};
if (mergeResults) {
// update files according to the merge results
modifiedStatus = applyModifiedVersion(files, mergeResults, mergeStrategy, // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
componentWithDependencies.component.originallySharedDir);
}
const shouldDependenciesSaveAsComponents = yield consumer.shouldDependenciesSavedAsComponents([id]);
componentWithDependencies.component.dependenciesSavedAsComponents = shouldDependenciesSaveAsComponents[0].saveDependenciesAsComponents;
return {
applyVersionResult: {
id,
filesStatus: Object.assign(filesStatus, modifiedStatus)
},
component: componentWithDependencies
};
});
return _applyVersion.apply(this, arguments);
}
function applyModifiedVersion(componentFiles, mergeResults, mergeStrategy, sharedDir) {
const filesStatus = {};
if (mergeResults.hasConflicts && mergeStrategy !== _mergeVersion().MergeOptions.manual) return filesStatus;
mergeResults.modifiedFiles.forEach(file => {
const filePath = path().normalize(file.filePath);
const pathWithSharedDir = p => sharedDir ? path().join(sharedDir, p) : p;
const foundFile = componentFiles.find(componentFile => pathWithSharedDir(componentFile.relative) === filePath);
if (!foundFile) throw new (_generalError().default)(`file ${filePath} not found`);
if (file.conflict) {
// @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
foundFile.contents = Buffer.from(file.conflict);
filesStatus[file.filePath] = _mergeVersion().FileStatus.manual;
} else if (file.output) {
// @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
foundFile.contents = Buffer.from(file.output);
filesStatus[file.filePath] = _mergeVersion().FileStatus.merged;
} else {
throw new (_generalError().default)('file does not have output nor conflict');
}
});
mergeResults.addFiles.forEach(file => {
componentFiles.push(file.fsFile);
filesStatus[file.filePath] = _mergeVersion().FileStatus.added;
});
mergeResults.overrideFiles.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`); // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
foundFile.contents = file.fsFile.contents;
filesStatus[file.filePath] = _mergeVersion().FileStatus.overridden;
});
return filesStatus;
}
;