@teambit/workspace
Version:
120 lines (118 loc) • 5.78 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getAutoTagInfo = getAutoTagInfo;
exports.getAutoTagPending = getAutoTagPending;
function _graphlib() {
const data = _interopRequireWildcard(require("graphlib"));
_graphlib = function () {
return data;
};
return data;
}
function _semver() {
const data = _interopRequireDefault(require("semver"));
_semver = function () {
return data;
};
return data;
}
function _componentId() {
const data = require("@teambit/component-id");
_componentId = function () {
return data;
};
return data;
}
function _componentVersion() {
const data = require("@teambit/component-version");
_componentVersion = function () {
return data;
};
return data;
}
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
async function getAutoTagPending(consumer, changedComponents) {
const autoTagInfo = await getAutoTagInfo(consumer, changedComponents);
return autoTagInfo.map(a => a.component);
}
async function getAutoTagInfo(consumer, changedComponents) {
if (!changedComponents.length) return [];
const potentialComponents = potentialComponentsForAutoTagging(consumer, changedComponents);
const idsToLoad = new (_componentId().ComponentIdList)(...potentialComponents, ...changedComponents);
const {
components
} = await consumer.loadComponents(idsToLoad, false);
const graph = buildGraph(components);
const autoTagResults = [];
components.forEach(component => {
const bitId = component.componentId;
const idStr = bitId.toStringWithoutVersion();
if (!graph.hasNode(idStr)) return;
// preorder gets all dependencies and dependencies of dependencies and so on.
// we loop over the dependencies of a component
// @ts-ignore
const dependenciesStr = _graphlib().default.alg.preorder(graph, idStr);
const dependenciesBitIds = dependenciesStr.map(depStr => graph.node(depStr));
const triggeredDependencies = dependenciesBitIds.filter(dependencyId => {
const changedComponentId = changedComponents.searchWithoutVersion(dependencyId);
if (!changedComponentId) {
// the dependency hasn't changed, so the component is not auto-tag pending
return false;
}
if (changedComponents.searchWithoutVersion(bitId)) {
// the dependency has changed but also the component itself, so it's going to be tagged anyway
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".
// the case when it returns false is when the changedComponentId.version is smaller than
// edgeId.version. it happens for example, when A => B (A depends on B), B has changed, A is
// a candidate. A has the B dependency saved in the model with version 2.0.0 and B is now
// tagged with 1.0.1. So, because A has B with a higher version already, we don't want to
// auto-tag it and downgrade its B version.
if ((0, _componentVersion().isTag)(changedComponentId.version) && (0, _componentVersion().isTag)(dependencyId.version)) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return _semver().default.gte(changedComponentId.version, dependencyId.version);
}
// when they're not tags but snaps, it is impossible to snap from a detached head so a
// component is always candidate when its dependencies have changed.
return true;
});
if (triggeredDependencies.length) {
autoTagResults.push({
component,
triggeredBy: _componentId().ComponentIdList.fromArray(triggeredDependencies)
});
}
});
return autoTagResults;
}
function buildGraph(components) {
const graph = new (_graphlib().Graph)();
const componentsIds = _componentId().ComponentIdList.fromArray(components.map(c => c.id));
components.forEach(component => {
const idStr = component.id.toStringWithoutVersion();
component.getAllDependencies().forEach(dependency => {
if (componentsIds.searchWithoutVersion(dependency.id)) {
const depId = dependency.id.toStringWithoutVersion();
// save the full ComponentID of a string id to be able to retrieve it later with no confusion
if (!graph.hasNode(idStr)) graph.setNode(idStr, component.id);
if (!graph.hasNode(depId)) graph.setNode(depId, dependency.id);
graph.setEdge(idStr, depId);
}
});
});
return graph;
}
function potentialComponentsForAutoTagging(consumer, modifiedComponents) {
const candidateComponentsIds = consumer.bitMap.getAllBitIds();
// if a modified component is in candidates array, remove it from the array as it will be already
// tagged with the correct version
const idsWithoutModified = candidateComponentsIds.filter(candidateId => !modifiedComponents.hasWithoutVersion(candidateId));
return _componentId().ComponentIdList.fromArray(idsWithoutModified);
}
//# sourceMappingURL=auto-tag.js.map