msync
Version:
Easily manage building and syncing multiple node-modules in a flexibly defined workspace.
98 lines (97 loc) • 3.46 kB
JavaScript
import { constants, elapsed, exec, inquirer, listr, loadSettings, log, plural, semver, formatModuleName, time, } from '../common';
import { printTable } from './ls.cmd';
export const name = 'publish';
export const alias = ['p', 'pub'];
export const description = 'Publishes all modules that are ahead of NPM.';
export const args = {};
export async function cmd(args) {
await publish({});
}
export async function publish(options = {}) {
var _a;
const settings = await loadSettings({ npm: true, spinner: true });
if (!settings) {
log.warn.yellow(constants.CONFIG_NOT_FOUND_ERROR);
return;
}
const modules = settings.modules.filter(pkg => isPublishRequired(pkg));
printTable(modules);
const total = modules.length;
if (total === 0) {
log.info.gray(`✨✨ No modules need to be published.\n`);
return;
}
log.info();
if (!(await promptYesNo(`Publish ${total} ${plural('module', total)} to NPM now?`))) {
log.info();
return;
}
log.info.gray(`Publishing to NPM:\n`);
const startedAt = new Date();
const publishCommand = (pkg) => {
const install = pkg.engine === 'YARN' ? 'yarn install' : 'npm install';
return `${install} && npm publish`;
};
let current;
const publishResult = await runCommand(modules, publishCommand, {
concurrent: false,
exitOnError: true,
onStart: pkg => (current = pkg),
});
if (publishResult.success) {
log.info(`\n✨✨ Done ${log.gray(elapsed(startedAt))}\n`);
}
else {
log.info();
log.info.yellow(`Failed on module:`);
log.info.gray(` ${formatModuleName(((_a = current) === null || _a === void 0 ? void 0 : _a.name) || 'UNKNOWN')}`);
log.info();
log.error(publishResult.error);
}
}
const runCommand = async (modules, cmd, options) => {
const { concurrent, exitOnError } = options;
let errors = [];
const task = (pkg) => {
return {
title: log.gray(`${formatModuleName(pkg.name)}: ${cmd(pkg)}`),
task: async () => {
options.onStart(pkg);
const command = `cd ${pkg.dir} && ${cmd(pkg)}`;
const res = await exec.cmd.run(command, { silent: true });
if (res.error) {
errors = [...errors, { pkg, info: res.info, errors: res.errors }];
throw res.error;
}
await time.wait(2500);
return res;
},
};
};
const tasks = modules.map(pkg => task(pkg));
const runner = listr(tasks, { concurrent, exitOnError });
try {
await runner.run();
return { success: true, error: null };
}
catch (error) {
errors.forEach(({ info }) => {
info.forEach(line => log.info(line));
});
return { success: false, error };
}
};
async function promptYesNo(message) {
const res = (await inquirer.prompt({
type: 'list',
name: 'answer',
message,
choices: [
{ name: 'yes', value: 'true' },
{ name: 'no', value: 'false' },
],
}));
const answer = res.answer;
return answer === 'true' ? true : false;
}
const isPublishRequired = (pkg) => { var _a; return ((_a = pkg.npm) === null || _a === void 0 ? void 0 : _a.latest) ? semver.gt(pkg.version, pkg.npm.latest) : false; };