@teambit/checkout
Version:
255 lines (252 loc) • 13.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.CheckoutCmd = void 0;
exports.checkoutOutput = checkoutOutput;
function _chalk() {
const data = _interopRequireDefault(require("chalk"));
_chalk = function () {
return data;
};
return data;
}
function _cli() {
const data = require("@teambit/cli");
_cli = function () {
return data;
};
return data;
}
function _componentModules() {
const data = require("@teambit/component.modules.merge-helper");
_componentModules = function () {
return data;
};
return data;
}
function _legacy() {
const data = require("@teambit/legacy.constants");
_legacy = function () {
return data;
};
return data;
}
function _componentId() {
const data = require("@teambit/component-id");
_componentId = function () {
return data;
};
return data;
}
function _bitError() {
const data = require("@teambit/bit-error");
_bitError = function () {
return data;
};
return data;
}
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
class CheckoutCmd {
constructor(checkout) {
this.checkout = checkout;
_defineProperty(this, "name", 'checkout <to> [component-pattern]');
_defineProperty(this, "arguments", [{
name: 'to',
description: "permitted values: `[head, latest, reset, {specific-version}, {head~x}]`. 'head' - last snap/tag. 'latest' - semver latest tag. 'reset' - removes local changes"
}, {
name: 'component-pattern',
description: _legacy().COMPONENT_PATTERN_HELP
}]);
_defineProperty(this, "description", 'switch between component versions or remove local changes');
_defineProperty(this, "helpUrl", 'reference/components/merging-changes#checkout-snaps-to-the-working-directory');
_defineProperty(this, "group", 'version-control');
_defineProperty(this, "extendedDescription", `checkout components to specified versions or remove local changes. most commonly used as 'bit checkout head' to get latest versions.
the \`<to>\` argument accepts these values:
- head: checkout to last snap/tag (most common usage)
- specific version: checkout to exact version (e.g. 'bit checkout 1.0.5 component-name')
- head~x: go back x generations from head (e.g. 'head~2' for two versions back)
- latest: checkout to latest semver tag
- reset: remove local modifications and restore original files (also restores deleted component directories)
when on lanes, 'checkout head' only affects lane components. to update main components, run 'bit lane merge main'.`);
_defineProperty(this, "alias", 'U');
_defineProperty(this, "options", [['i', 'interactive-merge', 'when a component is modified and the merge process found conflicts, display options to resolve them'], ['r', 'auto-merge-resolve <merge-strategy>', 'in case of merge conflict, resolve according to the provided strategy: [ours, theirs, manual]'], ['', 'manual', 'same as "--auto-merge-resolve manual". in case of merge conflict, write the files with the conflict markers'], ['a', 'all', 'all components'], ['e', 'workspace-only', "only relevant for 'bit checkout head' when on a lane. don't import components from the remote lane that are not already in the workspace"], ['v', 'verbose', 'showing verbose output for inspection'], ['x', 'skip-dependency-installation', 'do not auto-install dependencies of the imported components'], ['', 'force-ours', 'do not merge, preserve local files as is'], ['', 'force-theirs', 'do not merge, just overwrite with incoming files'], ['', 'include-new-from-scope', "relevant for 'bit checkout head'. import components from the defaultScope that don't exist in the workspace"]]);
_defineProperty(this, "loader", true);
}
async report([to, componentPattern], {
interactiveMerge = false,
forceOurs,
forceTheirs,
autoMergeResolve,
manual,
all = false,
workspaceOnly = false,
verbose = false,
skipDependencyInstallation = false,
revert = false,
includeNewFromScope = false
}) {
if (forceOurs && forceTheirs) {
throw new (_bitError().BitError)('please use either --force-ours or --force-theirs, not both');
}
if (autoMergeResolve && autoMergeResolve !== 'ours' && autoMergeResolve !== 'theirs' && autoMergeResolve !== 'manual') {
throw new (_bitError().BitError)('--auto-merge-resolve must be one of the following: [ours, theirs, manual]');
}
if (manual) autoMergeResolve = 'manual';
if (workspaceOnly && to !== _legacy().HEAD) {
throw new (_bitError().BitError)('--workspace-only is only relevant when running "bit checkout head" on a lane');
}
if (includeNewFromScope && to !== _legacy().HEAD) {
throw new (_bitError().BitError)('--include-new-from-scope is only relevant when running "bit checkout head"');
}
const checkoutProps = {
promptMergeOptions: interactiveMerge,
mergeStrategy: autoMergeResolve,
all,
verbose,
isLane: false,
skipNpmInstall: skipDependencyInstallation,
workspaceOnly,
revert,
forceOurs,
forceTheirs,
includeNewFromScope
};
to = String(to); // it can be a number in case short-hash is used
if (to === _legacy().HEAD) checkoutProps.head = true;else if (to === _legacy().LATEST) checkoutProps.latest = true;else if (to === 'reset') checkoutProps.reset = true;else if (to === 'main') checkoutProps.main = true;else if (to.startsWith(`${_legacy().HEAD}~`)) {
const ancestor = parseInt(to.split('~')[1]);
if (Number.isNaN(ancestor)) throw new (_bitError().BitError)(`the character after "${_legacy().HEAD}~" must be a number, got ${ancestor}`);
checkoutProps.ancestor = ancestor;
} else {
if (!_componentId().ComponentID.isValidVersion(to)) throw new (_bitError().BitError)(`the specified version "${to}" is not a valid version`);
checkoutProps.version = to;
}
const checkoutResults = await this.checkout.checkoutByCLIValues(componentPattern || '', checkoutProps);
return checkoutOutput(checkoutResults, checkoutProps);
}
}
exports.CheckoutCmd = CheckoutCmd;
function checkoutOutput(checkoutResults, checkoutProps, alternativeTitle) {
const {
components,
version,
failedComponents,
removedComponents,
addedComponents,
leftUnresolvedConflicts,
workspaceConfigUpdateResult,
newFromLane,
newFromLaneAdded,
newFromScope,
installationError,
compilationError
} = checkoutResults;
const {
head,
reset,
latest,
main,
revert,
verbose,
all
} = checkoutProps;
// components that failed for no legitimate reason. e.g. merge-conflict.
const realFailedComponents = (failedComponents || []).filter(f => !f.unchangedLegitimately);
if (realFailedComponents.length) {
throw new Error('checkout should throw in case of errors');
}
// components that weren't checked out for legitimate reasons, e.g. up-to-date.
const notCheckedOutComponents = failedComponents || [];
const hasSkippedComponents = notCheckedOutComponents.length > 0 && all && !verbose;
const getNotCheckedOutOutputMinimal = () => {
if (!notCheckedOutComponents.length) return '';
if (all && !verbose) {
return (0, _cli().formatDetailsHint)(`full list of ${notCheckedOutComponents.length} skipped component(s)`);
}
const items = notCheckedOutComponents.map(failedComponent => (0, _cli().formatItem)(`${failedComponent.id.toString()} - ${failedComponent.unchangedMessage}`));
return (0, _cli().formatSection)('checkout skipped', '', items);
};
const getNotCheckedOutOutputDetailed = () => {
if (!notCheckedOutComponents.length) return '';
const items = notCheckedOutComponents.map(failedComponent => (0, _cli().formatItem)(`${failedComponent.id.toString()} - ${failedComponent.unchangedMessage}`));
return (0, _cli().formatSection)('checkout skipped', '', items);
};
const getWsConfigUpdateLogs = () => {
const logs = workspaceConfigUpdateResult?.logs;
if (!logs || !logs.length) return '';
const logsStr = logs.join('\n');
return `${(0, _cli().formatTitle)('verbose logs of workspace config update')}\n${logsStr}`;
};
const getConflictSummary = () => {
if (!components || !components.length || !leftUnresolvedConflicts) return '';
const title = (0, _cli().formatTitle)(`${_cli().warnSymbol} files with conflicts summary`);
const conflictSummary = (0, _componentModules().conflictSummaryReport)(components);
const suggestion = (0, _cli().formatHint)(`fix the conflicts above manually and then run "bit install".\nonce ready, snap/tag the components to persist the changes`);
return `${title}\n${conflictSummary.conflictStr}\n\n${suggestion}`;
};
const getSuccessfulOutput = () => {
if (!components || !components.length) return '';
const switchedOrReverted = revert ? 'reverted' : 'switched';
if (components.length === 1) {
const component = components[0];
const componentName = reset ? component.id.toString() : component.id.toStringWithoutVersion();
if (reset) return (0, _cli().formatSuccessSummary)(`successfully reset ${_chalk().default.bold(componentName)}`);
const title = alternativeTitle || `successfully ${switchedOrReverted} ${_chalk().default.bold(componentName)} to version ${_chalk().default.bold(head || latest ? component.id.version : version)}`;
return [(0, _cli().formatSuccessSummary)(title), (0, _componentModules().applyVersionReport)(components, false)].filter(Boolean).join('\n');
}
if (reset) {
const items = components.map(component => (0, _cli().formatItem)(component.id.toString()));
return (0, _cli().formatSection)('reset components', '', items);
}
const getVerOutput = () => {
if (head) return 'their head version';
if (latest) return 'their latest version';
if (main) return 'their main version';
return `version ${_chalk().default.bold(version)}`;
};
const versionOutput = getVerOutput();
const title = alternativeTitle || `successfully ${switchedOrReverted} ${components.length} components to ${versionOutput}`;
const showVersion = head || reset;
return [(0, _cli().formatSuccessSummary)(title), (0, _componentModules().applyVersionReport)(components, true, showVersion)].filter(Boolean).join('\n');
};
const getNewOnLaneOutput = () => {
if (!newFromLane?.length) return '';
const title = newFromLaneAdded ? 'new components from lane' : 'new components on lane (not added)';
const desc = newFromLaneAdded ? '' : 'omit --workspace-only flag to add them';
const items = newFromLane.map(c => (0, _cli().formatItem)(c.toString()));
return (0, _cli().formatSection)(title, desc, items);
};
const getNewFromScopeOutput = () => {
if (!newFromScope?.length) return '';
const items = newFromScope.map(c => (0, _cli().formatItem)(c.toString()));
return (0, _cli().formatSection)('new components from scope', '', items);
};
const getSummary = () => {
const checkedOut = components?.length || 0;
const notCheckedOutLegitimately = notCheckedOutComponents.length;
const title = (0, _cli().formatTitle)('Checkout Summary');
const checkedOutStr = `\nTotal Changed: ${_chalk().default.bold(checkedOut.toString())}`;
const unchangedLegitimatelyStr = `\nTotal Unchanged: ${_chalk().default.bold(notCheckedOutLegitimately.toString())}`;
const newOnLaneNum = newFromLane?.length || 0;
const newOnLaneAddedStr = newFromLaneAdded ? ' (added)' : ' (not added)';
const newOnLaneStr = newOnLaneNum ? `\nNew on lane${newOnLaneAddedStr}: ${_chalk().default.bold(newOnLaneNum.toString())}` : '';
const newFromScopeNum = newFromScope?.length || 0;
const newFromScopeStr = newFromScopeNum ? `\nNew from scope (imported): ${_chalk().default.bold(newFromScopeNum.toString())}` : '';
return title + checkedOutStr + unchangedLegitimatelyStr + newOnLaneStr + newFromScopeStr;
};
const buildOutput = notCheckedOutSection => (0, _cli().joinSections)([getWsConfigUpdateLogs(), notCheckedOutSection, getSuccessfulOutput(), (0, _componentModules().getRemovedOutput)(removedComponents), (0, _componentModules().getAddedOutput)(addedComponents), getNewOnLaneOutput(), getNewFromScopeOutput(), (0, _componentModules().getWorkspaceConfigUpdateOutput)(workspaceConfigUpdateResult), getConflictSummary(), getSummary(), (0, _componentModules().installationErrorOutput)(installationError), (0, _componentModules().compilationErrorOutput)(compilationError)]);
if (!hasSkippedComponents) {
return buildOutput(getNotCheckedOutOutputMinimal());
}
const data = buildOutput(getNotCheckedOutOutputMinimal());
const details = buildOutput(getNotCheckedOutOutputDetailed());
return {
data,
code: 0,
details
};
}
//# sourceMappingURL=checkout-cmd.js.map