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
JavaScript
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}`);
}
}
;