@gabortorma/mwm
Version:
Multi-repo Workspace Manager
158 lines (148 loc) • 5.75 kB
JavaScript
;
const consola = require('consola');
const args = require('../../shared/mwm.Bc81aV-e.cjs');
const pnpm = require('../../shared/mwm.DTKjIVEs.cjs');
const workspaceTools = require('workspace-tools');
const path = require('node:path');
const compareVersions = require('compare-versions');
require('node:process');
require('node:child_process');
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
const path__default = /*#__PURE__*/_interopDefaultCompat(path);
const packageFiles = ["package.json", "pnpm-lock.yaml"];
function processGitOutput(output) {
if (!output.success)
return [];
return output.stdout.split(/\n/).map((line) => line.trim()).filter((line) => !!line && !line.includes("node_modules"));
}
function isFilesCleanByCwd(cwd) {
const output = processGitOutput(workspaceTools.git(["status", "--porcelain"], { cwd }));
const isClean = output.length === 0;
return isClean;
}
function getPackageCwd(pkg) {
const packageInfos = workspaceTools.getPackageInfos(".");
const packageInfo = packageInfos[pkg];
return path__default.dirname(packageInfo.packageJsonPath);
}
function isWorkspaceClean(workspace) {
const cwd = getPackageCwd(workspace);
return isFilesCleanByCwd(cwd);
}
function commitChanges(workspace, pkg, newVersion) {
const cwd = getPackageCwd(workspace);
workspaceTools.git(["add", ...packageFiles], { cwd });
workspaceTools.git(["commit", "-m", `packages(upgrade): ${pkg} v${newVersion}`], { cwd });
}
function hasOldVersion(dependencies, pkg, version) {
if (!dependencies?.[pkg])
return false;
return compareVersions.compareVersions(dependencies[pkg], version) < 0;
}
function hasOldVersionInPackageInfo(packageInfo, pkg, version) {
const { dependencies, devDependencies, peerDependencies } = packageInfo;
return [dependencies, devDependencies, peerDependencies].some((deps) => hasOldVersion(deps, pkg, version));
}
function getNewVersion(pkg, workspace) {
const packageInfos = workspaceTools.getPackageInfos(".");
const { version: pkgVersion } = packageInfos[pkg];
if (hasOldVersionInPackageInfo(packageInfos[workspace], pkg, pkgVersion)) {
return pkgVersion;
}
}
function updateDeps(workspace, pkg, pkgVersion) {
pnpm.pnpmExec(["--filter", workspace, "update", `${pkg}@${pkgVersion}`]);
}
async function fixDependencies(workspace, pkg) {
const newVersion = getNewVersion(pkg, workspace);
if (!newVersion) {
consola.consola.log(`There are no new version from ${pkg}`);
return;
}
consola.consola.log(`New version found from ${pkg}:`, newVersion);
updateDeps(workspace, pkg, newVersion);
commitChanges(workspace, pkg, newVersion);
}
function getDependencyMap() {
return workspaceTools.createDependencyMap(workspaceTools.getPackageInfos("."));
}
function getDependencies(workspace) {
const dependencies = getDependencyMap().dependencies.get(workspace);
return Array.from(dependencies || []);
}
function getDependents(pkg) {
const dependents = getDependencyMap().dependents.get(pkg);
return Array.from(dependents || []);
}
function getDependentsWithoutWorkspaces(pkg, workspaces) {
return getDependents(pkg).filter((dependent) => !workspaces.has(dependent));
}
async function confirmMessage(message) {
const result = await consola.consola.prompt(message, {
type: "confirm"
});
args.checkCancel(result);
return result;
}
async function promptToContinue(workspace) {
const message = `${workspace} workspace ${packageFiles.join(" or ")} file modified.
Wanna continue release?`;
return confirmMessage(message);
}
async function promptToReleaseDependent(dependent, dependency) {
const newVersion = getNewVersion(dependency, dependent);
if (!newVersion)
return false;
const message = `${dependent} dependent of ${dependency}.
Wanna fix ${dependent}?`;
return confirmMessage(message);
}
async function promptToReleaseWorkspace(workspace) {
const message = `Wanna create a release from ${workspace}?`;
return confirmMessage(message);
}
async function checkWorkspaceToContinue(workspace) {
return isWorkspaceClean(workspace) || await promptToContinue(workspace);
}
function releasePackage(pkg) {
pnpm.pnpmExec(["--filter", pkg, "release"]);
}
async function releaseWorkspace(workspace, releaseDependencies, workspaces, release) {
if (!await checkWorkspaceToContinue(workspace)) {
consola.consola.warn(`${workspace} skipped`);
return;
}
if (releaseDependencies) {
const dependencies = getDependencies(workspace);
if (dependencies.length) {
consola.consola.log(` ${dependencies.length} workspace dependencies found:
- ${dependencies.join("\n - ")}`);
for (const dependency of dependencies) {
await releaseWorkspace(dependency, releaseDependencies, workspaces, release);
await fixDependencies(workspace, dependency);
}
}
}
if (release === true || await promptToReleaseWorkspace(workspace)) {
releasePackage(workspace);
workspaces.delete(workspace);
const dependents = getDependentsWithoutWorkspaces(workspace, workspaces);
for (const dependent of dependents) {
if (await promptToReleaseDependent(dependent, workspace)) {
workspaces.add(dependent);
}
}
}
}
async function releaseWorkspaces(workspaces, releaseDependencies) {
for (const workspace of workspaces) {
consola.consola.info("Release workspace:", workspace);
try {
await releaseWorkspace(workspace, releaseDependencies, workspaces, true);
} catch (error) {
consola.consola.error(`Some dependencies failed to fix or release for ${workspace}`, error);
}
}
}
exports.releaseWorkspace = releaseWorkspace;
exports.releaseWorkspaces = releaseWorkspaces;