UNPKG

msync

Version:

Easily manage building and syncing multiple node-modules in a flexibly defined workspace.

142 lines (139 loc) 4.58 kB
import { constants, dependsOn, filter, inquirer, loadSettings, log, R, savePackage, semver, updatePackageRef, formatModuleName, } from '../common'; import * as listCommand from './ls.cmd'; export const name = 'bump'; export const alias = 'b'; export const description = `Bumps a module version along with it's entire dependency graph.`; export const args = { '-i': 'Include ignored modules.', '-d': 'Dry run where no files are saved.', '-l': 'Local versions only. Does not retrieve NPM details.', }; export async function cmd(args) { const options = (args && args.options) || {}; await bump({ includeIgnored: options.i || false, local: options.l || false, dryRun: options.d || false, }); } export async function bump(options = {}) { const { includeIgnored = false, local = false, dryRun = false } = options; const save = !dryRun; const npm = !local; const settings = await loadSettings({ npm, spinner: npm }); if (!settings) { log.warn.yellow(constants.CONFIG_NOT_FOUND_ERROR); return; } const modules = settings.modules.filter(pkg => filter.includeIgnored(pkg, includeIgnored)); const module = await promptForModule(modules); if (!module) { return; } log.info(); const dependants = dependsOn(module, modules); listCommand.printTable([module], { includeIgnored: true, dependants }); if (dryRun) { log.info.gray(`Dry run...no files will be saved.\n`); } log.info(); const release = (await promptForReleaseType(module.version)); if (!release) { return; } log.info(); const bumped = await bumpModule({ release, pkg: module, allModules: modules, save, }); log.info(); log.info(bumped.log()); log.info(); if (dryRun) { log.info.gray(`\nNo files were saved.`); } else { log.info(); } } async function bumpModule(options) { const { release, pkg, allModules, save, level = 0, ref } = options; const dependants = dependsOn(pkg, allModules); const version = semver.inc(pkg.latest, release); const isRoot = ref === undefined; if (!version) { throw new Error(`Failed to '${release}' the semver ${pkg.latest}.`); } const head = ['update', 'module', 'version', 'dependants'].map(title => log.gray(title)); const table = options.table || log.table({ head, border: false }); const logPkgUpdate = (args) => { const { release, pkg, version } = args; let msg = ''; msg += ` ${log.yellow(release.toUpperCase())} `; msg += `${formatModuleName(pkg.name)} from ${pkg.latest}${log.yellow(version)} `; return log.gray(msg); }; if (ref) { table.add([ log.yellow(` ${release.toUpperCase()} `), formatModuleName(`${pkg.name} `), log.gray(`${pkg.latest}${log.magenta(version)} `), log.gray(`${formatModuleName(ref.name)} ${ref.fromVersion}${log.magenta(ref.toVersion)}`), ]); } const json = R.clone(pkg.json); json.version = version; if (save) { await savePackage(pkg.dir, json); } if (isRoot && dependants.length > 0) { log.info.gray('\nchanges:'); } for (const dependentPkg of dependants) { await updatePackageRef(dependentPkg, pkg.name, version, { save }); await bumpModule({ release: 'patch', pkg: dependentPkg, allModules, level: level + 1, ref: { name: pkg.name, fromVersion: pkg.latest, toVersion: version }, save, table, }); } return { table, log() { return ` ${log.info(logPkgUpdate({ release, pkg, version }))} ${table.toString()} ${log.gray('complete')} ${log.info(logPkgUpdate({ release, pkg, version }))} `.substring(1); }, }; } async function promptForModule(modules) { const choices = modules.map(pkg => ({ name: pkg.name, value: pkg.name })); const res = (await inquirer.prompt({ type: 'list', name: 'name', message: 'Select a module', choices, pageSize: 30, })); const name = res.name; return modules.find(pkg => pkg.name === name); } async function promptForReleaseType(version) { const choices = ['patch', 'minor', 'major']; const res = (await inquirer.prompt({ type: 'list', name: 'name', message: 'Release', choices, })); return res.name; }