@vortex.so/cli
Version:
CLI to interact with Vortex.
134 lines (131 loc) • 4.35 kB
JavaScript
import process from 'node:process';
import readline from 'node:readline';
import prompts from 'prompts';
import { SemVer, valid, lt, clean } from 'semver';
import c from 'chalk';
import 'figures';
import 'jiti';
import { Log } from '../../utils/log/index.mjs';
import { isPrerelease, releaseTypes } from './ship.release.mjs';
const log = new Log("Ship");
async function getOutput(operation) {
const { release } = operation.options;
const { name, oldVersion, oldBuild } = operation.state;
log.info(`Evolving ${c.bold.green(name)} version...`);
operation.update({
newBuild: oldBuild || 0 + 1
});
switch (release.type) {
case "prompt":
return promptForNewVersion(operation);
case "version":
const newSemVer = new SemVer(release.version, true);
return operation.update({
newVersion: newSemVer.version
});
default:
return operation.update({
release: release.type,
newVersion: getNextVersion(oldVersion, release)
});
}
}
function getNextVersion(oldVersion, release) {
const oldSemVer = new SemVer(oldVersion);
const newSemVer = oldSemVer.inc(release.type, release.preid);
if (isPrerelease(release.type) && newSemVer.prerelease.length === 2 && newSemVer.prerelease[0] === release.preid && String(newSemVer.prerelease[1]) === "0") {
newSemVer.prerelease[1] = "1";
newSemVer.format();
}
return newSemVer.version;
}
function getNextVersions(oldVersion, preid) {
const next = {};
for (const type of releaseTypes) {
next[type] = getNextVersion(oldVersion, { type, preid });
}
return next;
}
async function promptForNewVersion(operation) {
const { oldVersion, oldBuild } = operation.state;
const release = operation.options.release;
const next = getNextVersions(oldVersion, release.preid);
let isCancelled = false;
const answers = await prompts(
[
{
type: "autocomplete",
name: "release",
message: `Current version: ${c.bold.dim(oldVersion)}`,
initial: "patch",
choices: [
{ value: "major", title: `major - ${c.bold.red(next.major)}` },
{ value: "minor", title: `minor - ${c.bold.yellow(next.minor)}` },
{ value: "patch", title: `patch - ${c.bold.yellow(next.patch)}` },
{
value: "premajor",
title: `pre-release major - ${c.bold.green(next.premajor)}`
},
{
value: "preminor",
title: `pre-release minor - ${c.bold.green(next.preminor)}`
},
{
value: "prepatch",
title: `pre-release patch - ${c.bold.green(next.prepatch)}`
},
{
value: "prerelease",
title: `pre-release - ${c.bold.green(next.prerelease)}`
},
{ value: "none", title: `leave as-is - ${c.bold.dim(oldVersion)}` },
{ value: "custom", title: "custom..." }
]
},
{
type: (prev) => prev === "custom" ? "text" : null,
name: "custom",
message: "Enter the new version number:",
initial: oldVersion,
validate: (custom) => {
if (!valid(custom))
return "That's not a valid version number!";
if (lt(custom, oldVersion))
return "You can't downgrade. Please, grow up.";
else return true;
}
}
],
{
onCancel() {
readline.moveCursor(process.stdout, 0, -2);
readline.clearLine(process.stdout, 0);
readline.clearLine(process.stdout, 0);
isCancelled = true;
}
}
);
if (isCancelled)
throw new Error("Cancelled!");
const newVersion = answers.release === "none" ? oldVersion : answers.release === "custom" ? clean(answers.custom) : next[answers.release];
if (!newVersion) {
throw new Error("Cancelled, can't get new version.");
}
if (newVersion === oldVersion) {
throw new Error("Cancelled, version stays the same.");
}
const newBuild = oldBuild ? oldBuild + 1 : 1;
switch (answers.release) {
case "none":
return operation.update({ newVersion });
case "custom":
return operation.update({ newVersion, newBuild });
default:
return operation.update({
release: answers.release,
newVersion,
newBuild
});
}
}
export { getOutput, promptForNewVersion };