"use strict"; const conventionalRecommendedBump = require("conventional-recommended-bump"); const log = require("npmlog"); const semver = require("semver"); const { getChangelogConfig } = require("./get-changelog-config"); module.exports.recommendVersion = recommendVersion; /** * @param {import("@lerna/package").Package} pkg * @param {import("..").VersioningStrategy} type * @param {import("..").BaseChangelogOptions & { prereleaseId?: string }} commandOptions */ function recommendVersion(pkg, type, { changelogPreset, rootPath, tagPrefix, prereleaseId }) { log.silly(type, "for %s at %s", pkg.name, pkg.location); const options = { path: pkg.location, }; if (type === "independent") { options.lernaPackage = pkg.name; } else { // only fixed mode can have a custom tag prefix options.tagPrefix = tagPrefix; } const shouldBumpPrerelease = (releaseType, version) => { if (!semver.prerelease(version)) { return true; } switch (releaseType) { case "major": return semver.minor(version) !== 0 || semver.patch(version) !== 0; case "minor": return semver.patch(version) !== 0; default: return false; } }; // Ensure potential ValidationError in getChangelogConfig() is propagated correctly let chain = Promise.resolve(); chain = chain.then(() => getChangelogConfig(changelogPreset, rootPath)); chain = chain.then((config) => { // "new" preset API options.config = config; return new Promise((resolve, reject) => { conventionalRecommendedBump(options, (err, data) => { if (err) { return reject(err); } // result might be undefined because some presets are not consistent with angular // we still need to bump _something_ because lerna saw a change here let releaseType = data.releaseType || "patch"; if (prereleaseId) { const shouldBump = shouldBumpPrerelease(releaseType, pkg.version); const prereleaseType = shouldBump ? `pre${releaseType}` : "prerelease"; log.verbose(type, "increment %s by %s", pkg.version, prereleaseType); resolve(semver.inc(pkg.version, prereleaseType, prereleaseId)); } else { if (semver.major(pkg.version) === 0) { // According to semver, major version zero (0.y.z) is for initial // development. Anything MAY change at any time. The public API // SHOULD NOT be considered stable. The version 1.0.0 defines // the (initial stable) public API. // // To allow monorepos to use major version zero meaningfully, // the transition from 0.x to 1.x must be explicitly requested // by the user. Breaking changes MUST NOT automatically bump // the major version from 0.x to 1.x. // // The usual convention is to use semver-patch bumps for bugfix // releases and semver-minor for everything else, including // breaking changes. This matches the behavior of `^` operator // as implemented by `npm`. // if (releaseType === "major") { releaseType = "minor"; } } log.verbose(type, "increment %s by %s", pkg.version, releaseType); resolve(semver.inc(pkg.version, releaseType)); } }); }); }); return chain; }