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

290 lines (227 loc) 9.01 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.buildComponentsGraph = buildComponentsGraph; exports.buildComponentsGraphForComponentsAndVersion = buildComponentsGraphForComponentsAndVersion; exports.buildOneGraphForComponentsAndMultipleVersions = buildOneGraphForComponentsAndMultipleVersions; exports.buildOneGraphForComponents = buildOneGraphForComponents; exports.buildOneGraphForComponentsUsingScope = buildOneGraphForComponentsUsingScope; exports.topologicalSortComponentDependencies = topologicalSortComponentDependencies; 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 _pMapSeries() { const data = _interopRequireDefault(require("p-map-series")); _pMapSeries = function () { return data; }; return data; } function _graphlib() { const data = _interopRequireWildcard(require("graphlib")); _graphlib = function () { return data; }; return data; } function _graph() { const data = _interopRequireDefault(require("./graph")); _graph = function () { return data; }; return data; } function _loadFlattenedDependencies() { const data = _interopRequireDefault(require("../../consumer/component-ops/load-flattened-dependencies")); _loadFlattenedDependencies = function () { return data; }; return data; } function _generalError() { const data = _interopRequireDefault(require("../../error/general-error")); _generalError = function () { return data; }; return data; } function _bitId() { const data = require("../../bit-id"); _bitId = function () { return data; }; return data; } function buildComponentsGraph(components) { const graphDeps = new (_graphlib().Graph)(); const graphDevDeps = new (_graphlib().Graph)(); const graphExtensionDeps = new (_graphlib().Graph)(); components.forEach(component => { _setGraphEdges(component.id, component.dependencies, graphDeps); _setGraphEdges(component.id, component.devDependencies, graphDevDeps); _setGraphEdges(component.id, component.extensionDependencies, graphExtensionDeps); }); return { graphDeps, graphDevDeps, graphExtensionDeps }; } function buildComponentsGraphForComponentsAndVersion(components) { const graphDeps = new (_graphlib().Graph)(); const graphDevDeps = new (_graphlib().Graph)(); const graphExtensionDeps = new (_graphlib().Graph)(); components.forEach(({ component, version, versionStr }) => { const bitId = component.toBitId().changeVersion(versionStr); _setGraphEdges(bitId, version.dependencies, graphDeps); _setGraphEdges(bitId, version.devDependencies, graphDevDeps); _setGraphEdges(bitId, version.extensionDependencies, graphExtensionDeps); }); return { graphDeps, graphDevDeps, graphExtensionDeps }; } function buildOneGraphForComponentsAndMultipleVersions(components) { const graph = new (_graph().default)(); components.forEach(({ component, version }) => { const bitId = component.toBitId().changeVersion(undefined); const idStr = bitId.toString(); if (!graph.hasNode(idStr)) graph.setNode(idStr, bitId); version.getAllDependencies().forEach(dependency => { const depId = dependency.id.changeVersion(undefined); const depIdStr = depId.toString(); if (!graph.hasNode(depIdStr)) graph.setNode(depIdStr, depId); graph.setEdge(idStr, depIdStr); }); }); return graph; } /** * returns one graph that includes all dependencies types. each edge has a label of the dependency * type. the nodes content is the Component object. */ function buildOneGraphForComponents(_x, _x2) { return _buildOneGraphForComponents.apply(this, arguments); } /** * returns one graph that includes all dependencies types. each edge has a label of the dependency * type. the nodes content is the Component object. */ function _buildOneGraphForComponents() { _buildOneGraphForComponents = (0, _bluebird().coroutine)(function* (ids, consumer, direction = 'normal') { const { components } = yield consumer.loadComponents(_bitId().BitIds.fromArray(ids)); const componentsWithDeps = yield (0, _pMapSeries().default)(components, component => (0, _loadFlattenedDependencies().default)(consumer, component)); const allComponents = _ramda().default.flatten(componentsWithDeps.map(c => [c.component, ...c.allDependencies])); return buildGraphFromComponentsObjects(allComponents, direction); }); return _buildOneGraphForComponents.apply(this, arguments); } function buildOneGraphForComponentsUsingScope(_x3, _x4) { return _buildOneGraphForComponentsUsingScope.apply(this, arguments); } function _buildOneGraphForComponentsUsingScope() { _buildOneGraphForComponentsUsingScope = (0, _bluebird().coroutine)(function* (ids, scope, direction = 'normal') { const components = yield scope.getManyConsumerComponents(ids); const loadFlattened = /*#__PURE__*/function () { var _ref = (0, _bluebird().coroutine)(function* (component) { return scope.getManyConsumerComponents(component.getAllFlattenedDependencies()); }); return function loadFlattened(_x5) { return _ref.apply(this, arguments); }; }(); const dependencies = yield Promise.all(components.map(component => loadFlattened(component))); const allComponents = [...components, ..._ramda().default.flatten(dependencies)]; return buildGraphFromComponentsObjects(allComponents, direction); }); return _buildOneGraphForComponentsUsingScope.apply(this, arguments); } function buildGraphFromComponentsObjects(components, direction = 'normal') { const graph = new (_graph().default)(); // set vertices components.forEach(component => { const idStr = component.id.toString(); if (!graph.hasNode(idStr)) graph.setNode(idStr, component); }); // set edges const setEdge = (compId, depId, depType) => { const depIdStr = depId.toString(); if (direction === 'normal') { graph.setEdge(compId.toString(), depIdStr, depType); } else { graph.setEdge(depIdStr, compId.toString(), depType); } }; components.forEach(component => { Object.entries(component.depsIdsGroupedByType).forEach(([depType, depIds]) => { depIds.forEach(depId => { if (!graph.hasNode(depId.toString())) { throw new Error(`buildGraphFromComponentsObjects: missing node of ${depId.toString()}`); } setEdge(component.id, depId, depType); }); }); }); // uncomment to print the graph content // console.log('graph', graphLib.json.write(graph)) return graph; } function _setGraphEdges(bitId, dependencies, graph) { const id = bitId.toString(); dependencies.get().forEach(dependency => { const depId = dependency.id.toString(); // 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, bitId); if (!graph.hasNode(depId)) graph.setNode(depId, dependency.id); graph.setEdge(id, depId); }); } /** * throw for cyclic dependencies * it sorts only "dependencies", not "devDependencies" (nor compiler/tester dependencies). */ function topologicalSortComponentDependencies(componentWithDependencies) { const { graphDeps } = buildComponentsGraph([componentWithDependencies.component, ...componentWithDependencies.allDependencies]); const componentId = componentWithDependencies.component.id.toString(); let sortedComponents; if (!_graphlib().default.alg.isAcyclic(graphDeps)) { const circle = _graphlib().default.alg.findCycles(graphDeps); throw new (_generalError().default)(`unable to topological sort dependencies of ${componentId}, it has the following cyclic dependencies\n${circle}`); } try { sortedComponents = _graphlib().default.alg.topsort(graphDeps); const sortedComponentsIds = sortedComponents.map(s => graphDeps.node(s)); const sortedDependenciesIds = _ramda().default.tail(sortedComponentsIds); // the first one is the component itself const dependencies = sortedDependenciesIds.map(depId => { const matchDependency = componentWithDependencies.dependencies.find(dependency => dependency.id.isEqual(depId)); if (!matchDependency) throw new Error(`topologicalSortComponentDependencies, ${depId.toString()} is missing`); return matchDependency; }); componentWithDependencies.dependencies = dependencies; } catch (err) { throw new (_generalError().default)(`unable to topological sort dependencies of ${componentId}. Original error: ${err.message}`); } }