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
339 lines (276 loc) • 13.2 kB
JavaScript
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.bumpDependenciesVersions = bumpDependenciesVersions;
exports.getAutoTagPending = getAutoTagPending;
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 _semver() {
const data = _interopRequireDefault(require("semver"));
_semver = function () {
return data;
};
return data;
}
function _graphlib() {
const data = _interopRequireWildcard(require("graphlib"));
_graphlib = function () {
return data;
};
return data;
}
function _bitId() {
const data = require("../../bit-id");
_bitId = function () {
return data;
};
return data;
}
function _getFlattenedDependencies() {
const data = require("./get-flattened-dependencies");
_getFlattenedDependencies = function () {
return data;
};
return data;
}
function _componentsGraph() {
const data = require("../graph/components-graph");
_componentsGraph = function () {
return data;
};
return data;
}
const removeNils = _ramda().default.reject(_ramda().default.isNil);
/**
* bumping dependencies version, so-called "auto tagging" is needed when the currently tagged
* component has dependents. these dependents should have the updated version of the currently
* tagged component.
*
* to successfully accomplish the auto-tag, we do it with two rounds.
* it's easier to understand why another round of updateComponents() is needed by an example.
* say we have 3 components, bar/foo@0.0.1 depends on utils/is-string, utils/is-string@0.0.1 depends on
* utils/is-type, utils/is-type@0.0.1 with no dependencies.
* when utils/is-type is tagged, utils/is-string and bar/foo are updated in the first updateComponents() round.
* by looking at bar/foo dependencies, we find out that its utils/is-type dependency was updated to 0.0.2
* however, its utils/is-string dependency stays with 0.0.1, because utils/is-string was never part of
* taggedComponents array.
* this second round of updateComponents() makes sure that the auto-tagged components will be updated as well.
*
* another case when round2 is needed is when the tagged component has a cycle dependency.
* for example, A => B => C => A, and C is now tagged. the component C has the components A and B
* in its flattenedDependencies.
* Round1 updates A and B. It changes the C dependency to be 0.0.2 and bump their version to 0.0.2.
* Round2 updates the dependencies and flattenedDependencies of C to have A and B with version 0.0.2.
*/
function bumpDependenciesVersions(_x, _x2, _x3) {
return _bumpDependenciesVersions.apply(this, arguments);
}
/**
* by now we only bumped dependencies and flattened dependencies of the currently tagged components.
* however, in some cases, the currently tagged components, updated their dependencies and that
* update needs to be reflected in the flattenedDependencies of the auto-tagged components.
* @see auto-tagging.e2e file, case "then tagging the dependent of the skipped dependency" for a
* complete workflow of this use case.
*
* the process how to get the flattened dependencies here is similar to the one used when tagging
* components. (see tag-model-components file).
*/
function _bumpDependenciesVersions() {
_bumpDependenciesVersions = (0, _bluebird().coroutine)(function* (scope, potentialComponents, taggedComponents) {
const taggedComponentsIds = _bitId().BitIds.fromArray(taggedComponents.map(c => c.id)); // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
const allComponents = new (_bitId().BitIds)(...potentialComponents, ...taggedComponentsIds);
const componentsAndVersions = yield scope.getComponentsAndVersions(allComponents);
const graph = buildGraph(componentsAndVersions);
const updatedComponents = yield updateComponents(componentsAndVersions, scope, taggedComponentsIds, taggedComponentsIds, false, graph);
if (updatedComponents.length) {
const ids = updatedComponents.map(({
component
}) => component.toBitIdWithLatestVersion());
yield updateComponents(componentsAndVersions, scope, taggedComponentsIds, _bitId().BitIds.fromArray(ids), true, graph);
}
yield rewriteFlattenedDependencies(updatedComponents, componentsAndVersions, scope);
return updatedComponents;
});
return _bumpDependenciesVersions.apply(this, arguments);
}
function rewriteFlattenedDependencies(_x4, _x5, _x6) {
return _rewriteFlattenedDependencies.apply(this, arguments);
}
function _rewriteFlattenedDependencies() {
_rewriteFlattenedDependencies = (0, _bluebird().coroutine)(function* (updatedComponents, componentsAndVersions, scope) {
// get "componentsAndVersions" updated with the recently added versions
updatedComponents.forEach(updatedComponent => {
const id = updatedComponent.component.toBitId();
const componentAndVersion = componentsAndVersions.find(c => c.component.toBitId().isEqualWithoutVersion(id));
if (!componentAndVersion) throw new Error(`rewriteFlattenedDependencies failed finding id ${id.toString()}`);
componentAndVersion.version = updatedComponent.version;
componentAndVersion.versionStr = updatedComponent.versionStr;
});
const allDependenciesGraphs = (0, _componentsGraph().buildComponentsGraphForComponentsAndVersion)(componentsAndVersions);
const dependenciesCache = {};
const notFoundDependencies = new (_bitId().BitIds)();
const updateAll = updatedComponents.map( /*#__PURE__*/function () {
var _ref = (0, _bluebird().coroutine)(function* (updatedComponent) {
const id = updatedComponent.component.toBitId().changeVersion(updatedComponent.versionStr);
const {
flattenedDependencies,
flattenedDevDependencies
} = yield (0, _getFlattenedDependencies().getAllFlattenedDependencies)(scope, id, allDependenciesGraphs, dependenciesCache, notFoundDependencies);
updatedComponent.version.flattenedDependencies = flattenedDependencies;
updatedComponent.version.flattenedDevDependencies = flattenedDevDependencies;
});
return function (_x14) {
return _ref.apply(this, arguments);
};
}());
yield Promise.all(updateAll);
});
return _rewriteFlattenedDependencies.apply(this, arguments);
}
function updateComponents(_x7, _x8, _x9, _x10) {
return _updateComponents.apply(this, arguments);
}
function _updateComponents() {
_updateComponents = (0, _bluebird().coroutine)(function* (componentsAndVersions, scope, taggedComponents, changedComponents, isRound2 = false, graph) {
const autoTagResults = [];
const componentsToUpdateP = componentsAndVersions.map( /*#__PURE__*/function () {
var _ref2 = (0, _bluebird().coroutine)(function* ({
component,
version
}) {
let pendingUpdate = false;
const bitId = component.toBitId();
const idStr = bitId.toStringWithoutVersion();
if (!graph.hasNode(idStr)) return null;
const taggedId = taggedComponents.searchWithoutVersion(bitId);
const isTaggedComponent = Boolean(taggedId);
if (isTaggedComponent && !isRound2) {
// if isCommittedComponent is true, the only case it's needed to be updated is when it has
// cycle dependencies. in that case, it should be updated on the round2 only.
return null;
} // @ts-ignore
const allDependencies = _graphlib().default.alg.preorder(graph, idStr); // same as flattenDependencies
const triggeredBy = new (_bitId().BitIds)();
allDependencies.forEach(dependency => {
// @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
const dependencyId = graph.node(dependency);
const changedComponentId = changedComponents.searchWithoutVersion(dependencyId); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
if (changedComponentId && _semver().default.gt(changedComponentId.version, dependencyId.version)) {
updateDependencies(version, dependencyId, changedComponentId);
pendingUpdate = true;
triggeredBy.push(dependencyId);
}
});
if (pendingUpdate) {
const message = isTaggedComponent ? version.log.message : 'bump dependencies versions';
const getVersionToAdd = () => {
if (isRound2) {
// in case round2 updates the same component it updated in round1 or updated during the
// tag, we should use the same updated version, and not creating a new version.
if (isTaggedComponent) {
// @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
return taggedId.version;
}
const componentChangedInRound1 = changedComponents.searchWithoutVersion(bitId);
if (componentChangedInRound1) {
// @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
return componentChangedInRound1.version;
}
} // it's round 1 or it's round2 but wasn't updated before. create a new version
// @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
return component.getVersionToAdd();
};
const versionToAdd = getVersionToAdd();
autoTagResults.push({
component,
triggeredBy,
version,
versionStr: versionToAdd
});
return scope.sources.putAdditionalVersion(component, version, message, versionToAdd);
}
return null;
});
return function (_x15) {
return _ref2.apply(this, arguments);
};
}());
yield Promise.all(componentsToUpdateP);
return autoTagResults;
});
return _updateComponents.apply(this, arguments);
}
function updateDependencies(version, edgeId, changedComponentId) {
version.updateFlattenedDependency(edgeId, edgeId.changeVersion(changedComponentId.version));
const dependencyToUpdate = version.getAllDependencies().find(dependency => dependency.id.isEqualWithoutVersion(edgeId));
if (dependencyToUpdate) {
// it's a direct dependency
dependencyToUpdate.id = dependencyToUpdate.id.changeVersion(changedComponentId.version);
}
}
function buildGraph(componentsAndVersions) {
const graph = new (_graphlib().Graph)();
const componentsIds = _bitId().BitIds.fromArray(componentsAndVersions.map(c => c.component.toBitId()));
componentsAndVersions.forEach(({
component,
version,
versionStr
}) => {
const id = component.id();
version.getAllDependencies().forEach(dependency => {
if (componentsIds.searchWithoutVersion(dependency.id)) {
const depId = dependency.id.toStringWithoutVersion(); // save the full BitId of a string id to be able to retrieve it later with no confusion
if (!graph.hasNode(id)) graph.setNode(id, component.toBitId().changeVersion(versionStr));
if (!graph.hasNode(depId)) graph.setNode(depId, dependency.id);
graph.setEdge(id, depId);
}
});
});
return graph;
}
function getAutoTagPending(_x11, _x12, _x13) {
return _getAutoTagPending.apply(this, arguments);
}
function _getAutoTagPending() {
_getAutoTagPending = (0, _bluebird().coroutine)(function* (scope, potentialComponents, changedComponents) {
const componentsAndVersions = yield scope.getComponentsAndVersions( // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
new (_bitId().BitIds)(...potentialComponents, ...changedComponents));
const graph = buildGraph(componentsAndVersions);
const autoTagPendingComponents = componentsAndVersions.map(({
component
}) => {
const bitId = component.toBitId();
const idStr = bitId.toStringWithoutVersion();
if (!graph.hasNode(idStr)) return null; // @ts-ignore
const edges = _graphlib().default.alg.preorder(graph, idStr);
const isAutoTagPending = edges.some(edge => {
const edgeId = graph.node(edge);
const changedComponentId = changedComponents.searchWithoutVersion(edgeId);
if (!changedComponentId) return false;
if (changedComponents.searchWithoutVersion(bitId)) return false; // we only check whether a modified component may cause auto-tagging
// since it's only modified on the file-system, its version might be the same as the version stored in its
// dependents. That's why "semver.gte" is used instead of "semver.gt".
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return _semver().default.gte(changedComponentId.version, edgeId.version);
});
return isAutoTagPending ? component : null;
});
return removeNils(autoTagPendingComponents);
});
return _getAutoTagPending.apply(this, arguments);
}
;