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

339 lines (276 loc) 13.2 kB
"use strict"; 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); }