UNPKG

@gabortorma/mwm

Version:

Multi-repo Workspace Manager

158 lines (148 loc) 5.75 kB
'use strict'; 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;