UNPKG

@capgo/standard-version

Version:

replacement for `npm version` with automatic CHANGELOG generation

173 lines (156 loc) 5.01 kB
'use strict' const chalk = require('chalk') const checkpoint = require('../checkpoint') const conventionalRecommendedBump = require('conventional-recommended-bump') const figures = require('figures') const fs = require('fs') const DotGitignore = require('dotgitignore') const path = require('path') const presetLoader = require('../preset-loader') const runLifecycleScript = require('../run-lifecycle-script') const semver = require('semver') const writeFile = require('../write-file') const { resolveUpdaterObjectFromArgument } = require('../updaters') let configsToUpdate = {} async function Bump (args, version) { // reset the cache of updated config files each // time we perform the version bump step. configsToUpdate = {} if (args.skip.bump) return version let newVersion = version await runLifecycleScript(args, 'prerelease') const stdout = await runLifecycleScript(args, 'prebump') if (stdout && stdout.trim().length) args.releaseAs = stdout.trim() const release = await bumpVersion(args.releaseAs, version, args) if (!args.firstRelease) { const releaseType = getReleaseType(args.prerelease, release.releaseType, version) newVersion = semver.valid(releaseType) || semver.inc(version, releaseType, args.prerelease) updateConfigs(args, newVersion) } else { checkpoint(args, 'skip version bump on first release', [], chalk.red(figures.cross)) } await runLifecycleScript(args, 'postbump') return newVersion } Bump.getUpdatedConfigs = function () { return configsToUpdate } function getReleaseType (prerelease, expectedReleaseType, currentVersion) { if (isString(prerelease)) { if (isInPrerelease(currentVersion)) { if (shouldContinuePrerelease(currentVersion, expectedReleaseType) || getTypePriority(getCurrentActiveType(currentVersion)) > getTypePriority(expectedReleaseType) ) { return 'prerelease' } } return 'pre' + expectedReleaseType } else { return expectedReleaseType } } function isString (val) { return typeof val === 'string' } /** * if a version is currently in pre-release state, * and if it current in-pre-release type is same as expect type, * it should continue the pre-release with the same type * * @param version * @param expectType * @return {boolean} */ function shouldContinuePrerelease (version, expectType) { return getCurrentActiveType(version) === expectType } function isInPrerelease (version) { return Array.isArray(semver.prerelease(version)) } const TypeList = ['major', 'minor', 'patch'].reverse() /** * extract the in-pre-release type in target version * * @param version * @return {string} */ function getCurrentActiveType (version) { const typelist = TypeList for (let i = 0; i < typelist.length; i++) { if (semver[typelist[i]](version)) { return typelist[i] } } } /** * calculate the priority of release type, * major - 2, minor - 1, patch - 0 * * @param type * @return {number} */ function getTypePriority (type) { return TypeList.indexOf(type) } function bumpVersion (releaseAs, currentVersion, args) { return new Promise((resolve, reject) => { if (releaseAs) { return resolve({ releaseType: releaseAs }) } else { const presetOptions = presetLoader(args) if (typeof presetOptions === 'object') { if (semver.lt(currentVersion, '1.0.0')) presetOptions.preMajor = true } conventionalRecommendedBump({ debug: args.verbose && console.info.bind(console, 'conventional-recommended-bump'), preset: presetOptions, path: args.path, tagPrefix: args.tagPrefix, lernaPackage: args.lernaPackage }, function (err, release) { if (err) return reject(err) else return resolve(release) }) } }) } /** * attempt to update the version number in provided `bumpFiles` * @param args config object * @param newVersion version number to update to. * @return void */ function updateConfigs (args, newVersion) { const dotgit = DotGitignore() args.bumpFiles.forEach(function (bumpFile) { const updater = resolveUpdaterObjectFromArgument(bumpFile) if (!updater) { return } const configPath = path.resolve(process.cwd(), updater.filename) try { if (dotgit.ignore(configPath)) return const stat = fs.lstatSync(configPath) if (!stat.isFile()) return const contents = fs.readFileSync(configPath, 'utf8') checkpoint( args, 'bumping version in ' + updater.filename + ' from %s to %s', [updater.updater.readVersion(contents), newVersion] ) writeFile( args, configPath, updater.updater.writeVersion(contents, newVersion) ) // flag any config files that we modify the version # for // as having been updated. configsToUpdate[updater.filename] = true } catch (err) { if (err.code !== 'ENOENT') console.warn(err.message) } }) } module.exports = Bump